health
Senior Member
vâng tất nhiên là dùng cho cả nhà đc và dùng ổn định nhưng mà để so về độ tiện ích thì ko bằng next được bác ạVẫn dùng cho cả nhà dc, chịu khó thêm DoH/DoT từng thiết bị thủ công tí thôi![]()

vâng tất nhiên là dùng cho cả nhà đc và dùng ổn định nhưng mà để so về độ tiện ích thì ko bằng next được bác ạVẫn dùng cho cả nhà dc, chịu khó thêm DoH/DoT từng thiết bị thủ công tí thôi![]()
Nếu chỉ xét trường hợp gán IP chay vô router (đa phần router ko support DoT, DoH) thì IP của NextDns (45. xxx) sẽ là anycast (HK, Sing, hoặc 1 nước nào đó)vâng tất nhiên là dùng cho cả nhà đc và dùng ổn định nhưng mà để so về độ tiện ích thì ko bằng next được bác ạ![]()
Bị "Error: Process completed with exit code 1.” thì phải làm gì ạ?Đến thời điểm này các script đã được viết lại hoàn toàn mà theo mình là đã hoàn thiện vì... chưa nghĩ ra chức năng gì thêm. Để dễ dàng cập nhật nhất thì vào Settings và xóa repo đi rồi fork lại, nhớ lưu lại những list các bạn sang sử dụng.
View attachment 2079568
Các điểm khác biệt so với phiên bản ban đầu:
Ví dụ các định dạng
- Hỗ trợ chạy trên Windows với Node.js do đã loại bỏ gần như toàn bộ Shell Script
- Block tất cả subdomain thay vì chỉ domain được nhập vào.
- Các định dạng hỗ trợ và cách nhận biết:
- Hosts: có
127.0.0.1
hoặc0.0.0.0
ở đầu- Domain + Subdomains: có bao gồm subdomain của domain
- Adblock: có các ký tự
||
,^
,$
hay các URL(URL sẽ được bỏ qua do DNS không chặn được)- Wildcard Asterisk: có dấu
*.
ở đầu- Wildcard Domains (hoạt động tốt nhất): chỉ bao gồm subdomain cần thiết và số lượng ít hơn định dạng Domain + Subdomain
- Hỗ trợ chế độ siêu tốc với biến môi trường
FAST_MODE
- Hỗ trợ blocklist và allowlist từ biến môi trường
ALLOWLIST_URLS
vàBLOCKLIST_URLS
- Hỗ trợ ngừng workflow cũ đang chạy trước khi chạy workflow mới trong GitHub Actions
- Tốc dộ xử lý list nhanh hơn nhiều lần
- Log rõ ràng hơn list nào sẽ được sử dụng, bao nhiêu domain đã được xử lý
HaGeZi
View attachment 2079570
OISD
View attachment 2079571
Log
View attachment 2079576
View attachment 2079578
Cách sử dụng script mới nhất:
Lưu ý:
- Xóa repo cũ
- Fork lại
- Tạo thư mục
.github/workflows
- Copy
auto_update_github_action.yml
vào.github/workflows
- Cách thêm biến môi trường tương tự như thêm secret
FAST_MODE
: không thêm hoặc gán 0 sẽ chạy chế độ cũ, thêm và gán 1 sẽ chạy chế độ mớiALLOWLIST_URLS
vàBLOCKLIST_URLS
: không thêm sẽ chạy list có sẵn, thêm thì mỗi list 1 dòng
View attachment 2079574- Chạy workflow
Như vậy với lần cập nhật này chỉ cần copy 1 file vào
- Cloudflare giới hạn số lượng request là 1200 mỗi 5 phút: https://developers.cloudflare.com/fundamentals/api/reference/limits/
- Cách tính số lượng request: số lượng list cũ đã xóa + số lượng list mới + 1 request xóa rule cũ + 1 request tạo rule mới
View attachment 2079579
View attachment 2079580
=> 166 + 41 + 1 + 1 = 209 requests- Để chạy trên máy thì cài Node.js, copy file
.env.example
ra.env
rồi điền giá trị và chạy theo thứ tự:
Code:npm install node download_lists.js node cf_gateway_rule_delete.js node cf_list_delete.js node cf_list_create.js node cf_gateway_rule_create.js
.github/workflows
, sau đó thêm biến môi trường, có thay đổi gì thì sửa biến rồi chạy lại workflow là xong, không cần sửa file gì nữa![]()
Có vẻ là nhập sai ALLOWLIST_URLS với BLOCKLIST_URLSBị "Error: Process completed with exit code 1.” thì phải làm gì ạ?
addEventListener('scheduled', (event) => {
event.waitUntil(handleRequest());
});
addEventListener('fetch', (event) => {
return event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
const accountEmail = '';
const accountId= '';
const apiToken = '';
const domain = '';
const ip = await resolveDomain(domain);
if (ip) {
console.log(`The IP address of ${domain} is: ${ip}`);
const locationId = await getLocationId(accountId, apiToken, accountEmail);
if (locationId) {
console.log(`The location ID is: ${locationId}`);
const updateResult = await updateLocation(accountId, apiToken, locationId, ip, accountEmail);
if (updateResult) {
console.log("Update location successful:");
console.log(`Location ID: ${updateResult.id}`);
console.log(`Name: ${updateResult.name}`);
console.log(`IP: ${updateResult.networks[0].network}`);
console.log(`Subnet: ${updateResult.networks[0].network.split('/')[1]}`);
console.log(`Created At: ${updateResult.created_at}`);
console.log(`Updated At: ${updateResult.updated_at}`);
} else {
console.log("No location data found.");
}
} else {
console.log("No locations found.");
}
} else {
console.log(`Failed to resolve the IP address of ${domain}`);
}
return new Response('Worker execution completed', { status: 200 });
}
async function resolveDomain(domain) {
const apiURL = 'https://dns.google.com/resolve';
const queryURL = new URL(apiURL);
queryURL.searchParams.append('name', domain);
queryURL.searchParams.append('type', 'A');
const response = await fetch(queryURL);
const data = await response.json();
if (data.Answer instanceof Array && data.Answer.length > 0) {
const ipAddresses = data.Answer
.filter(answer => answer.type === 1)
.map(answer => answer.data);
return ipAddresses[0] || null;
} else {
return null;
}
}
async function getLocationId(accountId, apiToken, accountEmail) {
const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/gateway/locations`;
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json',
'X-Auth-Email': accountEmail,
'X-Auth-Key': apiToken
}
});
if (response.ok) {
const data = await response.json();
const result = data.result;
return result.length > 0 ? result[0].id : null;
} else {
return null;
}
}
async function updateLocation(accountId, apiToken, locationId, ip, accountEmail) {
const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/gateway/locations/${locationId}`;
const response = await fetch(url, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json',
'X-Auth-Email': accountEmail,
'X-Auth-Key': apiToken
},
body: JSON.stringify({
client_default: true,
ecs_support: true,
name: 'RouterZTE',
networks: [
{ network: `${ip}/32` }
]
})
});
if (response.ok) {
const data = await response.json();
return data.result || null;
} else {
return null;
}
}
(2) Add Cron TriggerHướng dẫn sử dụng Cloudflare Worker cập nhật Source IPv4 address trong DNS Location của Cloudflare Zero Trust qua DDNS:
View attachment 2084145
Ảnh mô tả.
1. Yêu cầu:
2. Bắt đầu:
- Có DDNS trỏ tới địa chỉ IP của Router cần match với Cloudflare.
- Có tài khoản Cloudflare (đa số đã có khi sử dụng Cloudflare Zero Trust như #1)
- Truy cập Worker: https://dash.cloudflare.com/?to=/:account/workers-and-pages
(1) Create Worker
View attachment 2084160(2) Điền mục "Name" là updatelocation hoặc bất kì
View attachment 2084167
(3) Kéo xuống cuối trang nhấn Deploy
View attachment 2084169
(4) Nhấn Edit code
View attachment 2084176
(5) Xoá tất cả các dòng code có sẵn, copy code dưới đây vào khung
(6) Chỉnh sửa các thông tin cho các biến sau:JavaScript:addEventListener('scheduled', (event) => { event.waitUntil(handleRequest()); }); addEventListener('fetch', (event) => { return event.respondWith(handleRequest(event.request)); }); async function handleRequest(request) { const accountEmail = '[email protected]'; const accountId= '09e1ce4beeee721da60efa2c06287551'; const apiToken = '181af2890ac1bea1646afc0cf12a529fd10d8'; const domain = 'userxvpn2409.ddns.net'; const ip = await resolveDomain(domain); if (ip) { console.log(`The IP address of ${domain} is: ${ip}`); const locationId = await getLocationId(accountId, apiToken, accountEmail); if (locationId) { console.log(`The location ID is: ${locationId}`); const updateResult = await updateLocation(accountId, apiToken, locationId, ip, accountEmail); if (updateResult) { console.log("Update location successful:"); console.log(`Location ID: ${updateResult.id}`); console.log(`Name: ${updateResult.name}`); console.log(`IP: ${updateResult.networks[0].network}`); console.log(`Subnet: ${updateResult.networks[0].network.split('/')[1]}`); console.log(`Created At: ${updateResult.created_at}`); console.log(`Updated At: ${updateResult.updated_at}`); } else { console.log("No location data found."); } } else { console.log("No locations found."); } } else { console.log(`Failed to resolve the IP address of ${domain}`); } return new Response('Worker execution completed', { status: 200 }); } async function resolveDomain(domain) { const apiURL = 'https://dns.google.com/resolve'; const queryURL = new URL(apiURL); queryURL.searchParams.append('name', domain); queryURL.searchParams.append('type', 'A'); const response = await fetch(queryURL); const data = await response.json(); if (data.Answer instanceof Array && data.Answer.length > 0) { const ipAddresses = data.Answer .filter(answer => answer.type === 1) .map(answer => answer.data); return ipAddresses[0] || null; } else { return null; } } async function getLocationId(accountId, apiToken, accountEmail) { const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/gateway/locations`; const response = await fetch(url, { headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json', 'X-Auth-Email': accountEmail, 'X-Auth-Key': apiToken } }); if (response.ok) { const data = await response.json(); const result = data.result; return result.length > 0 ? result[0].id : null; } else { return null; } } async function updateLocation(accountId, apiToken, locationId, ip, accountEmail) { const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/gateway/locations/${locationId}`; const response = await fetch(url, { method: 'PUT', headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json', 'X-Auth-Email': accountEmail, 'X-Auth-Key': apiToken }, body: JSON.stringify({ client_default: true, ecs_support: true, name: 'RouterZTE', networks: [ { network: `${ip}/32` } ] }) }); if (response.ok) { const data = await response.json(); return data.result || null; } else { return null; } }
View attachment 2084182
- accountEmail: email cloudflare của bạn.
- accountId: id account cloudflare của bạn, hướng dẫn lấy ở #1.
- apiToken: apiToken cloudflare của bạn, hướng dẫn lấy ở #1.
- domain: điền url của ddns của bạn vào.
(7) Save and deploy
View attachment 2084184
3. Tạo cron trigger để tự động chạy sau mỗi phút
View attachment 2084188
(1) Chọn vào Triggers
View attachment 2084190
Tiếp tục ở reply sau
:local ip
set $ip [/ip address get [find interface=<EDIT PPPOE INTERFACE>] address]
:local ipWithoutMask [:pick $ip 0 [:find $ip "/"]]
/tool fetch url="https://api.cloudflare.com/client/v4/accounts/<EDIT_ACCOUNT_ID>/gateway/locations/<EDIT_DNS_LOCATION>" \
mode=https http-method=put \
http-header-field="Authorization: Bearer <EDIT_API_TOKEN>, Content-Type: application/json, X-Auth-Email: <EDIT_ACCOUNT_EMAIL>, X-Auth-Key: <EDIT_API_TOKEN>" \
http-data="{ \"client_default\": true, \"ecs_support\": true, \"name\": \"RouterMikrotik\", \"networks\": [{ \"network\": \"$ip\" }] }" \
output=none
/system script run update
dst-path="result.txt"
Động voz nay sắp thành cái mương tele. Haha@ndhuy2308 nhiệt tình thế, là nick mới của hoàng tử sau khi được Việt kiều Timmy Võ - CTO của Cờ lâu phe châu Á nhận vào làm à?![]()
Tui xem chùa bấy lâu nay mới reg acc bác ơi@ndhuy2308 nhiệt tình thế, là nick mới của hoàng tử sau khi được Việt kiều Timmy Võ - CTO của Cờ lâu phe châu Á nhận vào làm à?![]()
Setup thử đi bác mướt lắmnhiệt tình quá, mà nick mới toe luôn![]()
e bị lỗi hình bác ơiĐến thời điểm này các script đã được viết lại hoàn toàn mà theo mình là đã hoàn thiện vì... chưa nghĩ ra chức năng gì thêm. Để dễ dàng cập nhật nhất thì vào Settings và xóa repo đi rồi fork lại, nhớ lưu lại những list các bạn sang sử dụng.
View attachment 2079568
Các điểm khác biệt so với phiên bản ban đầu:
Ví dụ các định dạng
- Hỗ trợ chạy trên Windows với Node.js do đã loại bỏ gần như toàn bộ Shell Script
- Block tất cả subdomain thay vì chỉ domain được nhập vào.
- Các định dạng hỗ trợ và cách nhận biết:
- Hosts: có
127.0.0.1
hoặc0.0.0.0
ở đầu- Domain + Subdomains: có bao gồm subdomain của domain
- Adblock: có các ký tự
||
,^
,$
hay các URL(URL sẽ được bỏ qua do DNS không chặn được)- Wildcard Asterisk: có dấu
*.
ở đầu- Wildcard Domains (hoạt động tốt nhất): chỉ bao gồm subdomain cần thiết và số lượng ít hơn định dạng Domain + Subdomain
- Hỗ trợ chế độ siêu tốc với biến môi trường
FAST_MODE
- Hỗ trợ blocklist và allowlist từ biến môi trường
ALLOWLIST_URLS
vàBLOCKLIST_URLS
- Hỗ trợ ngừng workflow cũ đang chạy trước khi chạy workflow mới trong GitHub Actions
- Tốc dộ xử lý list nhanh hơn nhiều lần
- Log rõ ràng hơn list nào sẽ được sử dụng, bao nhiêu domain đã được xử lý
HaGeZi
View attachment 2079570
OISD
View attachment 2079571
Log
View attachment 2079576
View attachment 2079578
Cách sử dụng script mới nhất:
Lưu ý:
- Xóa repo cũ
- Fork lại
- Tạo thư mục
.github/workflows
- Copy
auto_update_github_action.yml
vào.github/workflows
- Cách thêm biến môi trường tương tự như thêm secret
FAST_MODE
: không thêm hoặc gán 0 sẽ chạy chế độ cũ, thêm và gán 1 sẽ chạy chế độ mớiALLOWLIST_URLS
vàBLOCKLIST_URLS
: không thêm sẽ chạy list có sẵn, thêm thì mỗi list 1 dòng
View attachment 2079574- Chạy workflow
Như vậy với lần cập nhật này chỉ cần copy 1 file vào
- Cloudflare giới hạn số lượng request là 1200 mỗi 5 phút: https://developers.cloudflare.com/fundamentals/api/reference/limits/
- Cách tính số lượng request: số lượng list cũ đã xóa + số lượng list mới + 1 request xóa rule cũ + 1 request tạo rule mới
View attachment 2079579
View attachment 2079580
=> 166 + 41 + 1 + 1 = 209 requests- Để chạy trên máy thì cài Node.js, copy file
.env.example
ra.env
rồi điền giá trị và chạy theo thứ tự:
Code:npm install node download_lists.js node cf_gateway_rule_delete.js node cf_list_delete.js node cf_list_create.js node cf_gateway_rule_create.js
.github/workflows
, sau đó thêm biến môi trường, có thay đổi gì thì sửa biến rồi chạy lại workflow là xong, không cần sửa file gì nữa![]()
không được khúc nào? thông báo lỗi gì chụp màn hình lên đây?bác chủ thớt ơi, cập nhật bài hướng dẫn giúp e với, e làm theo ko được
chạy lại action thôi fen lâu lâu nó bị.View attachment 2085234
Nay tự nhiên bị lỗi này? Bác nào biết không ạ
Thank bác, bác gãi ngay đúng cái chỗ mình ngứa bấy lâu.Hướng dẫn sử dụng Cloudflare Worker cập nhật Source IPv4 address trong DNS Location của Cloudflare Zero Trust qua DDNS:
Vì sao lại có điều này:
- Các bạn muốn áp dụng cho tất cả các thiết bị trong nhà dùng DNS Cloudflare, các thiết bị không thể cài DoT, DoH.
- Tốc độ phản hồi rất nhanh.
- IP được cập nhật mỗi phút.
![]()
Ảnh mô tả.
1. Yêu cầu:
2. Bắt đầu:
- Có DDNS trỏ tới địa chỉ IP của Router cần match với Cloudflare.
- Có tài khoản Cloudflare (đa số đã có khi sử dụng Cloudflare Zero Trust như #1)
- Truy cập Worker: https://dash.cloudflare.com/?to=/:account/workers-and-pages
(1) Create Worker
![]()
(2) Điền mục "Name" là updatelocation hoặc bất kì
![]()
(3) Kéo xuống cuối trang nhấn Deploy
![]()
(4) Nhấn Edit code
![]()
(5) Xoá tất cả các dòng code có sẵn, copy code dưới đây vào khung
![]()
(6) Chỉnh sửa các thông tin cho các biến sau:JavaScript:addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request) { const accountEmail = ''; const accountId = ''; const apiToken = ''; const domain = ''; const ip = await resolveDomain(domain); if (ip) { console.log(`The IP address of ${domain} is: ${ip}`); const locationId = await getLocationId(accountId, apiToken, accountEmail); if (locationId) { console.log(`The location ID is: ${locationId}`); const updateResult = await updateLocation(accountId, apiToken, locationId, ip, accountEmail); if (updateResult) { console.log("Update location successful:"); console.log(`Location ID: ${updateResult.id}`); console.log(`Name: ${updateResult.name}`); console.log(`IP: ${updateResult.networks[0].network}`); console.log(`Subnet: ${updateResult.networks[0].network.split('/')[1]}`); console.log(`Created At: ${updateResult.created_at}`); console.log(`Updated At: ${updateResult.updated_at}`); } else { console.log("No location data found."); } } else { console.log("No locations found."); } } else { console.log(`Failed to resolve the IP address of ${domain}`); } return new Response('Worker execution completed', { status: 200 }); } async function resolveDomain(domain) { const apiURL = 'https://dns.google.com/resolve'; const queryURL = new URL(apiURL); queryURL.searchParams.append('name', domain); queryURL.searchParams.append('type', 'A'); const response = await fetch(queryURL); const data = await response.json(); if (data.Answer instanceof Array && data.Answer.length > 0) { const ipAddresses = data.Answer .filter(answer => answer.type === 1) .map(answer => answer.data); return ipAddresses[0] || null; } else { return null; } } async function getLocationId(accountId, apiToken, accountEmail) { const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/gateway/locations`; const response = await fetch(url, { headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json', 'X-Auth-Email': accountEmail, 'X-Auth-Key': apiToken } }); if (response.ok) { const data = await response.json(); const result = data.result; return result.length > 0 ? result[0].id : null; } else { return null; } } async function updateLocation(accountId, apiToken, locationId, ip, accountEmail) { const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/gateway/locations/${locationId}`; const response = await fetch(url, { method: 'PUT', headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json', 'X-Auth-Email': accountEmail, 'X-Auth-Key': apiToken }, body: JSON.stringify({ client_default: true, ecs_support: true, name: 'RouterZTE', networks: [ { network: `${ip}/32` } ] }) }); if (response.ok) { const data = await response.json(); return data.result || null; } else { return null; } }
- accountEmail: email cloudflare của bạn.
- accountId: id account cloudflare của bạn, hướng dẫn lấy ở #1.
- apiToken: apiToken cloudflare của bạn, hướng dẫn lấy ở #1.
- domain: điền url của ddns của bạn vào.
![]()
(7) Save and deploy
![]()
3. Tạo cron trigger để tự động chạy sau mỗi phút
![]()
(1) Chọn vào Triggers
![]()
Tiếp tục ở reply sau
*đã cập nhật ảnh lỗi
Theo Miêu biết thì router nào của Vịt Heo cũng bị đẩy cấu hình từ nhà mạng xuống đè lên. Muốn tự set cấu hình phải gọi kĩ thuật can thiệp từ trên tổng đàicó fen nào xài còn f670y của viettel cứ reset phát là nó về mặc định ko lưu cấu hình kolàm mấy nay cứ tưởng mình cấu hình lỗi chỗ nào vào modem mới thấy hóa ra nó ko lưu