Compare commits

...

4 Commits

Author SHA1 Message Date
Henrique Goncalves
081b485677
Merge 27f066bb8b into 098c1e9c54 2025-07-23 23:01:47 -03:00
Amir Zarrinkafsh
098c1e9c54
feat: add lefthook, megalinter and update editorconfig (#270)
This change adds [LeftHook](https://lefthook.dev/) as a GitHub hook management tool alongside [MegaLinter](https://megalinter.io/) to lint all relevant files within the repository.

For users that don't end up installing LeftHook for pre-commit hooks, megalinter picks up the necessary formatting changes and reports them.

* feat: add lefthook, megalinter and update editorconfig
* fix: lint commit ordering
* refactor: adjust megalinter reporters
* refactor: adjust description for cache domains
* refactor: single - for passing options
* refactor: add repo-specific fmt in megalinter pre-commands too
2025-07-24 10:59:52 +10:00
Henrique Goncalves
27f066bb8b
add cloudflare comment 2025-02-07 23:26:12 -03:00
Henrique Goncalves
b6ddac9531
add nextdns script 2025-02-07 23:25:30 -03:00
26 changed files with 771 additions and 492 deletions

View File

@ -2,7 +2,13 @@ root = true
[*] [*]
indent_style = space indent_style = space
indent_size = 4 indent_size = 2
trim_trailing_whitespace = true trim_trailing_whitespace = true
end_of_line = lf end_of_line = lf
insert_final_newline = true insert_final_newline = true
[*.md]
indent_size = 0
[*.sh]
indent_style = tab

55
.github/workflows/mega-linter.yml vendored Normal file
View File

@ -0,0 +1,55 @@
# MegaLinter GitHub Action configuration file
# More info at https://megalinter.io
---
name: MegaLinter
on:
pull_request:
branches:
- master
env:
GITHUB_STATUS_REPORTER: true
concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true
jobs:
megalinter:
name: MegaLinter
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: MegaLinter
uses: oxsecurity/megalinter@v8
id: ml
env:
VALIDATE_ALL_CODEBASE: >-
${{
github.event_name == 'push' &&
github.ref == 'refs/heads/master'
}}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Archive production artifacts
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: MegaLinter reports
include-hidden-files: "true"
path: |
megalinter-reports
mega-linter.log

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
scripts/output scripts/output
scripts/config.json scripts/config.json
megalinter-reports/

19
.lefthook.yml Normal file
View File

@ -0,0 +1,19 @@
pre-commit:
parallel: true
jobs:
- name: sort cache domains
run: jq ".cache_domains |= sort_by(.name)" {all_files} > {all_files}.tmp && mv {all_files}.tmp {all_files}
glob: "cache_domains.json"
- name: sort cdns
run: |
for f in {all_files}; do
sort -uo ${f} ${f}
done
env:
LC_ALL: C
glob: "*.txt"
- name: megalinter
run: docker run --rm -e USER=$(id -u) -e GROUP=$(id -g) -v "$PWD:/tmp/lint" oxsecurity/megalinter:v8
stage_fixed: true

39
.mega-linter.yml Normal file
View File

@ -0,0 +1,39 @@
# Configuration file for MegaLinter
#
# See all available variables at https://megalinter.io/latest/config-file/ and in
# linters documentation
APPLY_FIXES: all
FLAVOR_SUGGESTIONS: false
PRINT_ALPACA: false
SHOW_ELAPSED_TIME: true
ENABLE:
- ACTION
- BASH
- EDITORCONFIG
- JSON
- MARKDOWN
- SPELL
- YAML
DISABLE_LINTERS:
- JSON_V8R
- MARKDOWN_MARKDOWNLINT
- SPELL_CSPELL
- YAML_V8R
PRE_COMMANDS:
- command: apk add --no-cache yq
cwd: root
- command: yq -i ".cache_domains |= sort_by(.name)" cache_domains.json
cwd: workspace
- command: |
for f in *.txt; do
sort -uo ${f} ${f}
done
cwd: workspace
POST_COMMANDS:
- command: find . -user root -group root -exec chown ${USER}:${GROUP} {} \;
cwd: workspace

View File

@ -1,11 +1,11 @@
dist.blizzard.com *.cdn.blizzard.com
dist.blizzard.com.edgesuite.net
blizzard.vo.llnwd.net blizzard.vo.llnwd.net
blzddist1-a.akamaihd.net blzddist1-a.akamaihd.net
blzddist2-a.akamaihd.net blzddist2-a.akamaihd.net
blzddist3-a.akamaihd.net blzddist3-a.akamaihd.net
cdn.blizzard.com
dist.blizzard.com
dist.blizzard.com.edgesuite.net
edge.blizzard.top.comcast.net
level3.blizzard.com level3.blizzard.com
nydus.battle.net nydus.battle.net
edge.blizzard.top.comcast.net
cdn.blizzard.com
*.cdn.blizzard.com

View File

@ -1,136 +1,136 @@
{ {
"cache_domains": [ "cache_domains": [
{ {
"name": "arenanet", "name": "arenanet",
"description": "CDN for guild wars, HoT", "description": "CDN for Guild Wars, HoT",
"domain_files": ["arenanet.txt"] "domain_files": ["arenanet.txt"]
}, },
{ {
"name": "blizzard", "name": "blizzard",
"description": "CDN for blizzard/battle.net", "description": "CDN for Blizzard/Battle.net",
"domain_files": ["blizzard.txt"] "domain_files": ["blizzard.txt"]
}, },
{ {
"name": "cod", "name": "bsg",
"description": "CDN for Call of Duty", "description": "CDN for Battle State Games, Tarkov",
"domain_files": ["cod.txt"] "domain_files": ["bsg.txt"]
}, },
{ {
"name": "bsg", "name": "cityofheroes",
"description": "CDN for Battle State Games, Tarkov", "description": "CDN for City of Heroes (Homecoming)",
"domain_files": ["bsg.txt"] "domain_files": ["cityofheroes.txt"]
}, },
{ {
"name": "cityofheroes", "name": "cod",
"description": "CDN for City of Heroes (Homecoming)", "description": "CDN for Call of Duty",
"domain_files": ["cityofheroes.txt"] "domain_files": ["cod.txt"]
}, },
{ {
"name": "daybreak", "name": "daybreak",
"description": "Daybreak games CDN", "description": "CDN for Daybreak Games",
"domain_files": ["daybreak.txt"] "domain_files": ["daybreak.txt"]
}, },
{ {
"name": "epicgames", "name": "epicgames",
"description": "CDN for Epic Games", "description": "CDN for Epic Games",
"domain_files": ["epicgames.txt"] "domain_files": ["epicgames.txt"]
}, },
{ {
"name": "frontier", "name": "frontier",
"description": "CDN for frontier games", "description": "CDN for Frontier Games",
"domain_files": ["frontier.txt"] "domain_files": ["frontier.txt"]
}, },
{ {
"name": "nexusmods", "name": "neverwinter",
"description": "Nexus mods / skyrim content", "description": "Cryptic CDN for Neverwinter",
"domain_files": ["nexusmods.txt"] "domain_files": ["neverwinter.txt"]
}, },
{ {
"name": "neverwinter", "name": "nexusmods",
"description": "Cryptic CDN for Neverwinter", "description": "CDN for Nexus Mods/Skyrim content",
"domain_files": ["neverwinter.txt"] "domain_files": ["nexusmods.txt"]
}, },
{ {
"name": "nintendo", "name": "nintendo",
"description": "CDN for Nintendo consoles and download servers", "description": "CDN for Nintendo consoles",
"domain_files": ["nintendo.txt"] "domain_files": ["nintendo.txt"]
}, },
{ {
"name": "origin", "name": "origin",
"description": "CDN for origin", "description": "CDN for Origin",
"notes": "Should be enabled for HTTP traffic only or with a HTTPS proxy else origin client download fails", "notes": "Should be enabled for HTTP traffic only or with a HTTPS proxy else origin client download fails",
"mixed_content": true, "mixed_content": true,
"domain_files": ["origin.txt"] "domain_files": ["origin.txt"]
}, },
{ {
"name": "pathofexile", "name": "pathofexile",
"description": "CDN for Path Of Exile", "description": "CDN for Path Of Exile",
"domain_files": ["pathofexile.txt"] "domain_files": ["pathofexile.txt"]
}, },
{ {
"name": "renegadex", "name": "renegadex",
"description": "CDN for Renegade X", "description": "CDN for Renegade X",
"domain_files": ["renegadex.txt"] "domain_files": ["renegadex.txt"]
}, },
{ {
"name": "riot", "name": "riot",
"description": "CDN for riot games", "description": "CDN for Riot Games",
"domain_files": ["riot.txt"] "domain_files": ["riot.txt"]
}, },
{ {
"name": "rockstar", "name": "rockstar",
"description": "CDN for rockstar games", "description": "CDN for Rockstar Games",
"domain_files": ["rockstar.txt"] "domain_files": ["rockstar.txt"]
}, },
{ {
"name": "sony", "name": "sony",
"description": "CDN for sony / playstation", "description": "CDN for Sony/PSN",
"domain_files": ["sony.txt"] "domain_files": ["sony.txt"]
}, },
{ {
"name": "square", "name": "square",
"description": "CDN for Final Fantasy XIV", "description": "CDN for Final Fantasy XIV",
"domain_files": ["square.txt"] "domain_files": ["square.txt"]
}, },
{ {
"name": "steam", "name": "steam",
"description": "CDN for steam platform", "description": "CDN for Steam",
"domain_files": ["steam.txt"] "domain_files": ["steam.txt"]
}, },
{ {
"name": "uplay", "name": "teso",
"description": "CDN for uplay downloader", "description": "CDN for The Elder Scrolls Online",
"domain_files": ["uplay.txt"] "domain_files": ["teso.txt"]
}, },
{ {
"name": "teso", "name": "test",
"description": "CDN for The Elder Scrolls Online", "description": "CDN for Testing, recommended to enable for additional diagnostics",
"domain_files": ["teso.txt"] "domain_files": ["test.txt"]
}, },
{ {
"name": "warframe", "name": "uplay",
"description": "CDN for Warframe", "description": "CDN for Ubisoft",
"domain_files": ["warframe.txt"] "domain_files": ["uplay.txt"]
}, },
{ {
"name": "wargaming", "name": "warframe",
"description": "CDN for wargaming.net", "description": "CDN for Warframe",
"domain_files": ["wargaming.net.txt"] "domain_files": ["warframe.txt"]
}, },
{ {
"name": "wsus", "name": "wargaming",
"description": "CDN for windows updates", "description": "CDN for Wargaming.net",
"domain_files": ["windowsupdates.txt"] "domain_files": ["wargaming.net.txt"]
}, },
{ {
"name": "xboxlive", "name": "wsus",
"description": "CDN for xboxlive", "description": "CDN for Windows Updates",
"domain_files": ["xboxlive.txt"] "domain_files": ["windowsupdates.txt"]
}, },
{ {
"name": "test", "name": "xboxlive",
"description": "Test CDN, recommended to enable for additional diagnostics", "description": "CDN for Xbox Live",
"domain_files": ["test.txt"] "domain_files": ["xboxlive.txt"]
} }
] ]
} }

View File

@ -1,4 +1,4 @@
cdn-eu1.homecomingservers.com
cdn-na1.homecomingservers.com cdn-na1.homecomingservers.com
cdn-na2.homecomingservers.com cdn-na2.homecomingservers.com
cdn-na3.homecomingservers.com cdn-na3.homecomingservers.com
cdn-eu1.homecomingservers.com

View File

@ -1,6 +1,2 @@
# Daybreak games
#
# Do NOT cache manifest.patch.daybreakgames.com # Do NOT cache manifest.patch.daybreakgames.com
#
#PS2
pls.patch.daybreakgames.com pls.patch.daybreakgames.com

View File

@ -1,14 +1,14 @@
cdn1.epicgames.com
cdn2.epicgames.com
cdn.unrealengine.com cdn.unrealengine.com
cdn1.epicgames.com
cdn1.unrealengine.com cdn1.unrealengine.com
cdn2.epicgames.com
cdn2.unrealengine.com cdn2.unrealengine.com
cdn3.unrealengine.com cdn3.unrealengine.com
cloudflare.epicgamescdn.com
download.epicgames.com download.epicgames.com
download2.epicgames.com download2.epicgames.com
download3.epicgames.com download3.epicgames.com
download4.epicgames.com download4.epicgames.com
egdownload.fastly-edge.com
epicgames-download1.akamaized.net epicgames-download1.akamaized.net
fastly-download.epicgames.com fastly-download.epicgames.com
cloudflare.epicgamescdn.com
egdownload.fastly-edge.com

View File

@ -1,11 +1,11 @@
*.hac.lp1.d4c.nintendo.net
*.hac.lp1.eshop.nintendo.net
*.wup.eshop.nintendo.net
*.wup.shop.nintendo.net
ccs.cdn.wup.shop.nintendo.net.edgesuite.net ccs.cdn.wup.shop.nintendo.net.edgesuite.net
ecs-lp1.hac.shop.nintendo.net
geisha-wup.cdn.nintendo.net geisha-wup.cdn.nintendo.net
geisha-wup.cdn.nintendo.net.edgekey.net geisha-wup.cdn.nintendo.net.edgekey.net
idbe-wup.cdn.nintendo.net idbe-wup.cdn.nintendo.net
idbe-wup.cdn.nintendo.net.edgekey.net idbe-wup.cdn.nintendo.net.edgekey.net
ecs-lp1.hac.shop.nintendo.net
receive-lp1.dg.srv.nintendo.net receive-lp1.dg.srv.nintendo.net
*.wup.shop.nintendo.net
*.wup.eshop.nintendo.net
*.hac.lp1.d4c.nintendo.net
*.hac.lp1.eshop.nintendo.net

View File

@ -1,3 +1,3 @@
origin-a.akamaihd.net
lvlt.cdn.ea.com
cdn-patch.swtor.com cdn-patch.swtor.com
lvlt.cdn.ea.com
origin-a.akamaihd.net

View File

@ -1,2 +1,2 @@
patches.totemarts.services
patches.totemarts.games patches.totemarts.games
patches.totemarts.services

View File

@ -1,5 +1,5 @@
*.dyn.riotcdn.net
l3cdn.riotgames.com l3cdn.riotgames.com
worldwide.l3cdn.riotgames.com
riotgamespatcher-a.akamaihd.net riotgamespatcher-a.akamaihd.net
riotgamespatcher-a.akamaihd.net.edgesuite.net riotgamespatcher-a.akamaihd.net.edgesuite.net
*.dyn.riotcdn.net worldwide.l3cdn.riotgames.com

View File

@ -1,20 +1,20 @@
{ {
"combined_output": false, "combined_output": false,
"ips": { "ips": {
"steam": ["10.10.3.10", "10.10.3.11"], "steam": ["10.10.3.10", "10.10.3.11"],
"origin": "10.10.3.12", "origin": "10.10.3.12",
"blizzard": "10.10.3.13", "blizzard": "10.10.3.13",
"windows": "10.10.3.14", "windows": "10.10.3.14",
"riot": "10.10.3.15", "riot": "10.10.3.15",
"generic": "10.10.3.16" "generic": "10.10.3.16"
}, },
"cache_domains": { "cache_domains": {
"default": "generic", "default": "generic",
"blizzard": "blizzard", "blizzard": "blizzard",
"origin": "origin", "origin": "origin",
"riot": "riot", "riot": "riot",
"steam": "steam", "steam": "steam",
"wsus": "windows", "wsus": "windows",
"xboxlive": "windows" "xboxlive": "windows"
} }
} }

View File

@ -3,75 +3,76 @@ basedir=".."
outputdir="output/adguardhome" outputdir="output/adguardhome"
path="${basedir}/cache_domains.json" path="${basedir}/cache_domains.json"
export IFS=' ' export IFS=" "
test=$(which jq); if ! command -v jq >/dev/null; then
if [ $? -gt 0 ] ; then cat <<-EOF
echo "This script requires jq to be installed." This script requires jq to be installed.
echo "Your package manager should be able to find it" Your package manager should be able to find it
exit 1 EOF
exit 1
fi fi
cachenamedefault="disabled" cachenamedefault="disabled"
combinedoutput=$(jq -r ".combined_output" config.json) combinedoutput=$(jq -r ".combined_output" config.json)
while read line; do while read -r line; do
ip=$(jq ".ips[\"${line}\"]" config.json) ip=$(jq ".ips[\"${line}\"]" config.json)
declare "cacheip${line}"="${ip}" declare "cacheip${line}"="${ip}"
done <<< $(jq -r '.ips | to_entries[] | .key' config.json) done <<<"$(jq -r ".ips | to_entries[] | .key" config.json)"
while read line; do while read -r line; do
name=$(jq -r ".cache_domains[\"${line}\"]" config.json) name=$(jq -r ".cache_domains[\"${line}\"]" config.json)
declare "cachename$line"="$name" declare "cachename${line}"="${name}"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' config.json) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" config.json)"
rm -rf ${outputdir} rm -rf ${outputdir}
mkdir -p ${outputdir} mkdir -p ${outputdir}
while read entry; do while read -r entry; do
unset cacheip unset cacheip
unset cachename unset cachename
key=$(jq -r ".cache_domains[$entry].name" ${path}) key=$(jq -r ".cache_domains[$entry].name" ${path})
cachename="cachename${key}" cachename="cachename${key}"
if [ -z "${!cachename}" ]; then if [ -z "${!cachename}" ]; then
cachename="cachenamedefault" cachename=${cachenamedefault}
fi fi
if [[ ${!cachename} == "disabled" ]]; then if [[ ${cachename} == "disabled" ]]; then
continue; continue
fi fi
cacheipname="cacheip${!cachename}" cacheipname="cacheip${!cachename}"
cacheip=$(jq -r 'if type == "array" then .[] else . end' <<< ${!cacheipname} | xargs) cacheip=$(jq -r "if type == \"array\" then .[] else . end" <<<"${!cacheipname}" | xargs)
while read fileid; do while read -r fileid; do
while read filename; do while read -r filename; do
destfilename=$(echo ${filename} | sed -e 's/txt/conf/') destfilename=${filename//txt/conf}
outputfile=${outputdir}/${destfilename} outputfile=${outputdir}/${destfilename}
touch ${outputfile} touch "${outputfile}"
while read fileentry; do while read -r fileentry; do
# Ignore comments and newlines # Ignore comments and newlines
if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then
continue continue
fi fi
domainprefix="|" domainprefix="|"
if [[ $fileentry =~ ^\*\. ]]; then if [[ $fileentry =~ ^\*\. ]]; then
domainprefix="||" domainprefix="||"
fi fi
parsed=$(echo ${fileentry} | sed -e "s/^\*\.//") parsed="${fileentry#\*\.}"
if grep -q "${domainprefix}${parsed}^\$dnsrewrite" ${outputfile}; then if grep -q "${domainprefix}${parsed}^\$dnsrewrite" "${outputfile}"; then
continue continue
fi fi
for i in ${cacheip}; do for i in ${cacheip}; do
echo "${domainprefix}${parsed}^\$dnsrewrite=${i}" >> ${outputfile} echo "${domainprefix}${parsed}^\$dnsrewrite=${i}" >>"${outputfile}"
echo "${domainprefix}${parsed}^\$dnstype=AAAA" >> ${outputfile} echo "${domainprefix}${parsed}^\$dnstype=AAAA" >>"${outputfile}"
done done
done <<< $(cat ${basedir}/$filename | sort); done <<<"$(cat ${basedir}/"${filename}" | sort)"
done <<< $(jq -r ".cache_domains[${entry}].domain_files[${fileid}]" ${path}) done <<<"$(jq -r ".cache_domains[${entry}].domain_files[${fileid}]" ${path})"
done <<< $(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path}) done <<<"$(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path})"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' ${path}) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" ${path})"
if [[ ${combinedoutput} == "true" ]]; then if [[ ${combinedoutput} == "true" ]]; then
for file in ${outputdir}/*; do f=${file//${outputdir}\/} && f=${f//.conf} && echo "# ${f^}" >> ${outputdir}/lancache.conf && cat ${file} >> ${outputdir}/lancache.conf && rm ${file}; done for file in "${outputdir}"/*; do f=${file//${outputdir}\//} && f=${f//.conf/} && echo "# ${f^}" >>${outputdir}/lancache.conf && cat "${file}" >>${outputdir}/lancache.conf && rm "${file}"; done
fi fi
cat << EOF cat <<EOF
Configuration generation completed. Configuration generation completed.
Please copy the following files: Please copy the following files:

View File

@ -3,72 +3,73 @@ basedir=".."
outputdir="output/dnsmasq" outputdir="output/dnsmasq"
path="${basedir}/cache_domains.json" path="${basedir}/cache_domains.json"
export IFS=' ' export IFS=" "
test=$(which jq); if ! command -v jq >/dev/null; then
if [ $? -gt 0 ] ; then cat <<-EOF
echo "This script requires jq to be installed." This script requires jq to be installed.
echo "Your package manager should be able to find it" Your package manager should be able to find it
exit 1 EOF
exit 1
fi fi
cachenamedefault="disabled" cachenamedefault="disabled"
combinedoutput=$(jq -r ".combined_output" config.json) combinedoutput=$(jq -r ".combined_output" config.json)
while read -r line; do while read -r line; do
ip=$(jq ".ips[\"${line}\"]" config.json) ip=$(jq ".ips[\"${line}\"]" config.json)
declare "cacheip${line}"="${ip}" declare "cacheip${line}"="${ip}"
done <<< $(jq -r '.ips | to_entries[] | .key' config.json) done <<<"$(jq -r ".ips | to_entries[] | .key" config.json)"
while read -r line; do while read -r line; do
name=$(jq -r ".cache_domains[\"${line}\"]" config.json) name=$(jq -r ".cache_domains[\"${line}\"]" config.json)
declare "cachename${line}"="${name}" declare "cachename${line}"="${name}"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' config.json) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" config.json)"
rm -rf ${outputdir} rm -rf ${outputdir}
mkdir -p ${outputdir} mkdir -p ${outputdir}
while read -r entry; do while read -r entry; do
unset cacheip unset cacheip
unset cachename unset cachename
key=$(jq -r ".cache_domains[${entry}].name" ${path}) key=$(jq -r ".cache_domains[${entry}].name" ${path})
cachename="cachename${key}" cachename="cachename${key}"
if [ -z "${!cachename}" ]; then if [ -z "${!cachename}" ]; then
cachename="cachenamedefault" cachename=${cachenamedefault}
fi fi
if [[ ${!cachename} == "disabled" ]]; then if [[ ${cachename} == "disabled" ]]; then
continue; continue
fi fi
cacheipname="cacheip${!cachename}" cacheipname="cacheip${!cachename}"
cacheip=$(jq -r 'if type == "array" then .[] else . end' <<< ${!cacheipname} | xargs) cacheip=$(jq -r "if type == \"array\" then .[] else . end" <<<"${!cacheipname}" | xargs)
while read -r fileid; do while read -r fileid; do
while read -r filename; do while read -r filename; do
destfilename=$(echo ${filename} | sed -e 's/txt/conf/') destfilename=${filename//txt/conf}
outputfile=${outputdir}/${destfilename} outputfile=${outputdir}/${destfilename}
touch ${outputfile} touch "${outputfile}"
while read -r fileentry; do while read -r fileentry; do
# Ignore comments, newlines and wildcards # Ignore comments, newlines and wildcards
if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then
continue continue
fi fi
parsed=$(echo ${fileentry} | sed -e "s/^\*\.//") parsed="${fileentry#\*\.}"
for i in ${cacheip}; do for i in ${cacheip}; do
if ! grep -qx "address=/${parsed}/${i}" "${outputfile}"; then if ! grep -qx "address=/${parsed}/${i}" "${outputfile}"; then
echo "address=/${parsed}/${i}" >> "${outputfile}" echo "address=/${parsed}/${i}" >>"${outputfile}"
fi fi
if ! grep -qx "local=/${parsed}/" "${outputfile}"; then if ! grep -qx "local=/${parsed}/" "${outputfile}"; then
echo "local=/${parsed}/" >> "${outputfile}" echo "local=/${parsed}/" >>"${outputfile}"
fi fi
done done
done <<< $(cat ${basedir}/${filename} | sort); done <<<"$(cat ${basedir}/"${filename}" | sort)"
done <<< $(jq -r ".cache_domains[${entry}].domain_files[$fileid]" ${path}) done <<<"$(jq -r ".cache_domains[${entry}].domain_files[${fileid}]" ${path})"
done <<< $(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path}) done <<<"$(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path})"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' ${path}) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" ${path})"
if [[ ${combinedoutput} == "true" ]]; then if [[ ${combinedoutput} == "true" ]]; then
for file in ${outputdir}/*; do f=${file//${outputdir}\/} && f=${f//.conf} && echo "# ${f^}" >> ${outputdir}/lancache.conf && cat ${file} >> ${outputdir}/lancache.conf && rm ${file}; done for file in "${outputdir}"/*; do f=${file//${outputdir}\//} && f=${f//.conf/} && echo "# ${f^}" >>${outputdir}/lancache.conf && cat "${file}" >>${outputdir}/lancache.conf && rm "${file}"; done
fi fi
cat << EOF cat <<EOF
Configuration generation completed. Configuration generation completed.
Please copy the following files: Please copy the following files:

160
scripts/create-nextdns.py Normal file
View File

@ -0,0 +1,160 @@
#!/usr/bin/env python3
import json
import os
import random
import sys
import time
import urllib.error
import urllib.request
# Configuration
CACHE_DOMAINS_JSON = "cache_domains.json"
# Timing / Retry configuration
DELAY_SECONDS = 1 # delay between requests
MAX_RETRIES = 5 # maximum retries if rate limited
BACKOFF_FACTOR = 2 # exponential backoff multiplier
USER_AGENT = "python-requests/2.31.0" # for some reason, Cloudflare will block urllib's default user-agent
def post_redirect(base_url, api_key, payload):
"""Post a redirect entry using urllib.request. Implements retry logic if rate limited (429) is encountered."""
headers = {
"X-Api-Key": api_key,
"Content-Type": "application/json",
"User-Agent": USER_AGENT,
}
data = json.dumps(payload).encode("utf-8")
retries = 0
current_delay = DELAY_SECONDS
while retries <= MAX_RETRIES:
req = urllib.request.Request(
url=base_url, data=data, headers=headers, method="POST"
)
try:
with urllib.request.urlopen(req) as response:
status_code = response.getcode()
if status_code in [200, 201]:
return True, response.read().decode("utf-8")
else:
# For non-success status codes (other than 429)
return False, f"Unexpected status code: {status_code}"
except urllib.error.HTTPError as e:
if e.code == 429:
print(f"[*] Rate limited, waiting for {current_delay} seconds ...")
time.sleep(current_delay)
retries += 1
current_delay *= BACKOFF_FACTOR
else:
try:
error_body = e.read().decode("utf-8")
except Exception:
error_body = "No response body"
return False, f"HTTPError {e.code}, response: {error_body}"
except urllib.error.URLError as e:
return False, f"URLError: {e.reason}"
return False, "Max retries exceeded"
def run(profile_id, api_key, redirect_ip):
base_url = f"https://api.nextdns.io/profiles/{profile_id}/rewrites/"
# Read cache_domains.json
try:
with open(CACHE_DOMAINS_JSON, "r") as f:
cache_data = json.load(f)
except Exception as e:
print(f"[-] Failed to load {CACHE_DOMAINS_JSON}: {e}")
return
# Set to deduplicate domains
all_domains = set()
# Process each CDN entry in the JSON
for entry in cache_data.get("cache_domains", []):
domain_files = entry.get("domain_files", [])
for file_name in domain_files:
if os.path.exists(file_name):
with open(file_name, "r") as file:
# Read each line; ignore blank lines or comment lines
for line in file:
line = line.strip()
if not line or line.startswith("#") or line.startswith("//"):
continue
all_domains.add(line.lstrip("*."))
else:
print(f"[-] File '{file_name}' not found, skipping ...")
print("[*] Collected domains:")
for domain in sorted(all_domains):
print(f" - {domain}")
# Retrieve the existing rewrite entries from NextDNS API
headers = {
"X-Api-Key": api_key,
"User-Agent": USER_AGENT,
}
req = urllib.request.Request(url=base_url, headers=headers, method="GET")
try:
with urllib.request.urlopen(req) as response:
if response.getcode() != 200:
resp_body = response.read().decode("utf-8")
print(
f"[-] Failed to get existing redirects, status code: {response.getcode()}, response: {resp_body}"
)
return
resp_data = json.loads(response.read().decode("utf-8"))
except urllib.error.HTTPError as e:
try:
error_body = e.read().decode("utf-8")
except Exception:
error_body = "No response body"
print(
f"[-] Failed to get existing redirects, status code: {e.code}, response: {error_body}"
)
return
except urllib.error.URLError as e:
print(f"[-] Failed to get existing redirects, URLError: {e.reason}")
return
data = resp_data.get("data", [])
existing_domains = {entry.get("name") for entry in data}
print("\n[*] Existing domains:")
for domain in sorted(existing_domains):
print(f" - {domain}")
# For each domain, if missing in NextDNS, post a new redirect
for domain in all_domains:
if domain in existing_domains:
print(f"[*] Domain '{domain}' already exists, skipping...")
continue
payload = {
"name": domain,
"content": redirect_ip,
}
print(f"[+] Adding '{domain}'...")
success, post_resp = post_redirect(base_url, api_key, payload)
if not success:
print(f"[-] Failed to add redirect for '{domain}', response: {post_resp}")
# Delay between API calls to prevent triggering rate limits
time.sleep(DELAY_SECONDS + random.uniform(0, 1))
print("\n[+] Done!")
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: create-nextdns.py <profile_id> <api_key> <redirect_ip>")
sys.exit(1)
profile_id = sys.argv[1]
api_key = sys.argv[2]
redirect_ip = sys.argv[3]
run(profile_id, api_key, redirect_ip)

View File

@ -4,97 +4,97 @@ outputdir="output/rpz"
path="${basedir}/cache_domains.json" path="${basedir}/cache_domains.json"
basedomain=${1:-lancache.net} basedomain=${1:-lancache.net}
export IFS=' ' export IFS=" "
test=$(which jq); if ! command -v jq >/dev/null; then
if [ $? -gt 0 ] ; then cat <<-EOF
echo "This script requires jq to be installed." This script requires jq to be installed.
echo "Your package manager should be able to find it" Your package manager should be able to find it
exit 1 EOF
exit 1
fi fi
cachenamedefault="disabled" cachenamedefault="disabled"
while read line; do while read -r line; do
ip=$(jq ".ips[\"${line}\"]" config.json) ip=$(jq ".ips[\"${line}\"]" config.json)
declare "cacheip${line}"="${ip}" declare "cacheip${line}"="${ip}"
done <<< $(jq -r '.ips | to_entries[] | .key' config.json) done <<<"$(jq -r ".ips | to_entries[] | .key" config.json)"
while read line; do while read -r line; do
name=$(jq -r ".cache_domains[\"${line}\"]" config.json) name=$(jq -r ".cache_domains[\"${line}\"]" config.json)
declare "cachename${line}"="${name}" declare "cachename${line}"="${name}"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' config.json) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" config.json)"
rm -rf ${outputdir} rm -rf ${outputdir}
mkdir -p ${outputdir} mkdir -p ${outputdir}
outputfile=${outputdir}/db.rpz.${basedomain} outputfile=${outputdir}/db.rpz.${basedomain}
cat > ${outputfile} << EOF cat >"${outputfile}" <<EOF
\$TTL 60 ; default TTL \$TTL 60 ; default TTL
\$ORIGIN rpz.${basedomain}. \$ORIGIN rpz.${basedomain}.
@ SOA ns1.${basedomain}. admin.${basedomain}. ( @ SOA ns1.${basedomain}. admin.${basedomain}. (
$(date +%Y%m%d01) ; serial $(date +%Y%m%d01) ; serial
604800 ; refresh (1 week) 604800 ; refresh (1 week)
600 ; retry (10 mins) 600 ; retry (10 mins)
600 ; expire (10 mins) 600 ; expire (10 mins)
600 ; minimum (10 mins) 600 ; minimum (10 mins)
) )
NS ns1.${basedomain}. NS ns1.${basedomain}.
NS ns2.${basedomain}. NS ns2.${basedomain}.
EOF EOF
while read entry; do while read -r entry; do
unset cacheip unset cacheip
unset cachename unset cachename
key=$(jq -r ".cache_domains[${entry}].name" ${path}) key=$(jq -r ".cache_domains[${entry}].name" ${path})
cachename="cachename${key}" cachename="cachename${key}"
if [ -z "${!cachename}" ]; then if [ -z "${!cachename}" ]; then
cachename="cachenamedefault" cachename=${cachenamedefault}
fi fi
if [[ ${!cachename} == "disabled" ]]; then if [[ ${cachename} == "disabled" ]]; then
continue; continue
fi fi
cacheipname="cacheip${!cachename}" cacheipname="cacheip${!cachename}"
cacheip=$(jq -r 'if type == "array" then .[] else . end' <<< ${!cacheipname} | xargs) cacheip=$(jq -r "if type == \"array\" then .[] else . end" <<<"${!cacheipname}" | xargs)
while read fileid; do while read -r fileid; do
while read filename; do while read -r filename; do
echo "" >> ${outputfile} echo "" >>"${outputfile}"
echo "; $(echo ${filename} | sed -e 's/.txt$//')" >> ${outputfile} echo "; ${filename//.txt//}" >>"${outputfile}"
destfilename=$(echo ${filename} | sed -e 's/txt/conf/') while read -r fileentry; do
while read fileentry; do # Ignore comments and newlines
# Ignore comments and newlines if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then
if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then continue
continue fi
fi parsed=${fileentry}
parsed=$(echo ${fileentry}) if grep -qx "^\"${parsed}\". " "${outputfile}"; then
if grep -qx "^\"${parsed}\". " ${outputfile}; then continue
continue fi
fi t=""
t="" for i in ${cacheip}; do
for i in ${cacheip}; do # only one cname per domain is allowed
# only one cname per domain is allowed if [[ ${t} = "CNAME" ]]; then
if [[ ${t} = "CNAME" ]]; then continue
continue fi
fi # for cnames you must use a fqdn with trailing dot
# for cnames you must use a fqdn with trailing dot t="CNAME"
t="CNAME" if [[ ${i} =~ ^[0-9\.]+$ ]]; then
if [[ ${i} =~ ^[0-9\.]+$ ]] ; then t="A"
t="A" elif [[ ! ${i} =~ \.$ ]]; then
elif [[ ! ${i} =~ \.$ ]] ; then i="${i}."
i="${i}." fi
fi printf "%-50s IN %s %s\n" \
printf "%-50s IN %s %s\n" \ "${parsed}" \
"${parsed}" \ "${t}" \
"${t}" \ "${i}" \
"${i}" \ >>"${outputfile}"
>> ${outputfile} done
done done <<<"$(cat ${basedir}/"${filename}" | sort)"
done <<< $(cat ${basedir}/${filename} | sort); done <<<"$(jq -r ".cache_domains[${entry}].domain_files[${fileid}]" ${path})"
done <<< $(jq -r ".cache_domains[${entry}].domain_files[${fileid}]" ${path}) done <<<"$(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path})"
done <<< $(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path}) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" ${path})"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' ${path})
cat << EOF cat <<EOF
Configuration generation completed. Configuration generation completed.
Please include the rpz zone in your bind configuration" Please include the rpz zone in your bind configuration"
@ -102,12 +102,12 @@ Please include the rpz zone in your bind configuration"
- configure the zone and use it - configure the zone and use it
options { options {
[...] [...]
response-policy {zone "rpz.${basedomain}";}; response-policy {zone "rpz.${basedomain}";};
[...] [...]
} }
zone "rpz.$basedomain" { zone "rpz.$basedomain" {
type master; type master;
file "/etc/bind/db.rpz.${basedomain}"; file "/etc/bind/db.rpz.${basedomain}";
}; };
EOF EOF

View File

@ -4,65 +4,65 @@ outputdir="output/squid"
path="${basedir}/cache_domains.json" path="${basedir}/cache_domains.json"
REGEX="^\\*\\.(.*)$" REGEX="^\\*\\.(.*)$"
export IFS=' ' export IFS=" "
test=$(which jq); if ! command -v jq >/dev/null; then
if [ $? -gt 0 ] ; then cat <<-EOF
echo "This script requires jq to be installed." This script requires jq to be installed.
echo "Your package manager should be able to find it" Your package manager should be able to find it
exit 1 EOF
exit 1
fi fi
cachenamedefault="disabled" cachenamedefault="disabled"
while read -r line; do while read -r line; do
name=$(jq -r ".cache_domains[\"${line}\"]" config.json) name=$(jq -r ".cache_domains[\"${line}\"]" config.json)
declare "cachename${line}"="${name}" declare "cachename${line}"="${name}"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' config.json) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" config.json)"
rm -rf ${outputdir} rm -rf ${outputdir}
mkdir -p ${outputdir} mkdir -p ${outputdir}
while read -r entry; do while read -r entry; do
unset cachename unset cachename
key=$(jq -r ".cache_domains[$entry].name" ${path}) key=$(jq -r ".cache_domains[$entry].name" ${path})
cachename="cachename${key}" cachename="cachename${key}"
if [ -z "${!cachename}" ]; then if [ -z "${!cachename}" ]; then
cachename="cachenamedefault" cachename=${cachenamedefault}
fi fi
if [[ ${!cachename} == "disabled" ]]; then if [[ ${cachename} == "disabled" ]]; then
continue; continue
fi fi
while read -r fileid; do while read -r fileid; do
while read -r filename; do while read -r filename; do
destfilename=$(echo ${!cachename}.txt) destfilename=${!cachename}.txt
outputfile=${outputdir}/${destfilename} outputfile=${outputdir}/${destfilename}
touch ${outputfile} touch "${outputfile}"
while read -r fileentry; do while read -r fileentry; do
# Ignore comments # Ignore comments
if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then
continue continue
fi fi
# Ha wildcards to squid wildcards # Ha wildcards to squid wildcards
parsed=$(echo ${fileentry} | sed -e "s/^\*\./\./") parsed="${fileentry#\*}"
# If we have cdn.thing and *.cdn.thing in cache_domains # If we have cdn.thing and *.cdn.thing in cache_domains
# Squid requires ONLY cdn.thing # Squid requires ONLY cdn.thing
# #
# If the fileentry starts with *.cdn.thing # If the fileentry starts with *.cdn.thing
if [[ ${fileentry} =~ $REGEX ]]; then if [[ ${fileentry} =~ $REGEX ]]; then
# Does the cache_domains file also contain cdn.thing # Does the cache_domains file also contain cdn.thing
grep "${BASH_REMATCH[1]}" ${basedir}/${filename} | grep -v "${fileentry}" > /dev/null if grep "${BASH_REMATCH[1]}" ${basedir}/"${filename}" | grep -v "${fileentry}" >/dev/null; then
if [[ $? -eq 0 ]]; then # Skip *.cdn.thing as cdn.thing will be collected earlier/later
# Skip *.cdn.thing as cdn.thing will be collected earlier/later continue
continue fi
fi fi
fi echo "${parsed}" >>"${outputfile}"
echo "${parsed}" >> "${outputfile}" done <<<"$(cat ${basedir}/"${filename}" | sort)"
done <<< $(cat ${basedir}/${filename} | sort); done <<<"$(jq -r ".cache_domains[${entry}].domain_files[${fileid}]" ${path})"
done <<< $(jq -r ".cache_domains[${entry}].domain_files[${fileid}]" ${path}) done <<<"$(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path})"
done <<< $(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path}) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" ${path})"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' ${path})
cat << EOF cat <<EOF
Configuration generation completed. Configuration generation completed.
Please copy the following files: Please copy the following files:

View File

@ -3,74 +3,75 @@ basedir=".."
outputdir="output/unbound" outputdir="output/unbound"
path="${basedir}/cache_domains.json" path="${basedir}/cache_domains.json"
export IFS=' ' export IFS=" "
test=$(which jq); if ! command -v jq >/dev/null; then
if [ $? -gt 0 ] ; then cat <<-EOF
echo "This script requires jq to be installed." This script requires jq to be installed.
echo "Your package manager should be able to find it" Your package manager should be able to find it
exit 1 EOF
exit 1
fi fi
cachenamedefault="disabled" cachenamedefault="disabled"
combinedoutput=$(jq -r ".combined_output" config.json) combinedoutput=$(jq -r ".combined_output" config.json)
while read line; do while read -r line; do
ip=$(jq ".ips[\"${line}\"]" config.json) ip=$(jq ".ips[\"${line}\"]" config.json)
declare "cacheip${line}"="${ip}" declare "cacheip${line}"="${ip}"
done <<< $(jq -r '.ips | to_entries[] | .key' config.json) done <<<"$(jq -r ".ips | to_entries[] | .key" config.json)"
while read line; do while read -r line; do
name=$(jq -r ".cache_domains[\"${line}\"]" config.json) name=$(jq -r ".cache_domains[\"${line}\"]" config.json)
declare "cachename${line}"="${name}" declare "cachename${line}"="${name}"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' config.json) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" config.json)"
rm -rf ${outputdir} rm -rf ${outputdir}
mkdir -p ${outputdir} mkdir -p ${outputdir}
while read entry; do while read -r entry; do
unset cacheip unset cacheip
unset cachename unset cachename
key=$(jq -r ".cache_domains[${entry}].name" ${path}) key=$(jq -r ".cache_domains[${entry}].name" ${path})
cachename="cachename${key}" cachename="cachename${key}"
if [ -z "${!cachename}" ]; then if [ -z "${!cachename}" ]; then
cachename="cachenamedefault" cachename=${cachenamedefault}
fi fi
if [[ ${!cachename} == "disabled" ]]; then if [[ ${cachename} == "disabled" ]]; then
continue; continue
fi fi
cacheipname="cacheip${!cachename}" cacheipname="cacheip${!cachename}"
cacheip=$(jq -r 'if type == "array" then .[] else . end' <<< ${!cacheipname} | xargs) cacheip=$(jq -r "if type == \"array\" then .[] else . end" <<<"${!cacheipname}" | xargs)
while read fileid; do while read -r fileid; do
while read filename; do while read -r filename; do
destfilename=$(echo ${filename} | sed -e 's/txt/conf/') destfilename=${filename//txt/conf}
outputfile=${outputdir}/${destfilename} outputfile=${outputdir}/${destfilename}
touch ${outputfile} touch "${outputfile}"
while read fileentry; do while read -r fileentry; do
# Ignore comments and newlines # Ignore comments and newlines
if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then if [[ ${fileentry} == \#* ]] || [[ -z ${fileentry} ]]; then
continue continue
fi fi
parsed=$(echo ${fileentry} | sed -e "s/^\*\.//") parsed="${fileentry#\*\.}"
if grep -qx " local-zone: \"${parsed}\" redirect" ${outputfile}; then if grep -qx " local-zone: \"${parsed}\" redirect" "${outputfile}"; then
continue continue
fi fi
if [[ $(head -n 1 ${outputfile}) != "server:" ]]; then if [[ $(head -n 1 "${outputfile}") != "server:" ]]; then
echo "server:" >> ${outputfile} echo "server:" >>"${outputfile}"
fi fi
echo " local-zone: \"${parsed}\" redirect" >> ${outputfile} echo " local-zone: \"${parsed}\" redirect" >>"${outputfile}"
for i in ${cacheip}; do for i in ${cacheip}; do
echo " local-data: \"${parsed} 30 IN A ${i}\"" >> ${outputfile} echo " local-data: \"${parsed} 30 IN A ${i}\"" >>"${outputfile}"
done done
done <<< $(cat ${basedir}/${filename} | sort); done <<<"$(cat ${basedir}/"${filename}" | sort)"
done <<< $(jq -r ".cache_domains[${entry}].domain_files[${fileid}]" ${path}) done <<<"$(jq -r ".cache_domains[${entry}].domain_files[${fileid}]" ${path})"
done <<< $(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path}) done <<<"$(jq -r ".cache_domains[${entry}].domain_files | to_entries[] | .key" ${path})"
done <<< $(jq -r '.cache_domains | to_entries[] | .key' ${path}) done <<<"$(jq -r ".cache_domains | to_entries[] | .key" ${path})"
if [[ ${combinedoutput} == "true" ]]; then if [[ ${combinedoutput} == "true" ]]; then
for file in ${outputdir}/*; do f=${file//${outputdir}\/} && f=${f//.conf} && echo "# ${f^}" >> ${outputdir}/lancache.conf && cat ${file} >> ${outputdir}/lancache.conf && rm ${file}; done for file in "${outputdir}"/*; do f=${file//${outputdir}\//} && f=${f//.conf/} && echo "# ${f^}" >>${outputdir}/lancache.conf && cat "${file}" >>${outputdir}/lancache.conf && rm "${file}"; done
fi fi
cat << EOF cat <<EOF
Configuration generation completed. Configuration generation completed.
Please copy the following files: Please copy the following files:

View File

@ -1,16 +1,16 @@
gs2.ww.prod.dl.playstation.net
*.gs2.ww.prod.dl.playstation.net
*.gs2.sonycoment.loris-e.llnwd.net
gs2-ww-prod.psn.akadns.net
*.gs2-ww-prod.psn.akadns.net *.gs2-ww-prod.psn.akadns.net
gs2.ww.prod.dl.playstation.net.edgesuite.net *.gs2.sonycoment.loris-e.llnwd.net
*.gs2.ww.prod.dl.playstation.net
*.gs2.ww.prod.dl.playstation.net.edgesuite.net *.gs2.ww.prod.dl.playstation.net.edgesuite.net
gs-sec.ww.np.dl.playstation.net
gs2-ww-prod.psn.akadns.net
gs2.ww.prod.dl.playstation.net
gs2.ww.prod.dl.playstation.net.edgesuite.net
gst.prod.dl.playstation.net
playstation4.sony.akadns.net playstation4.sony.akadns.net
psnobj.prod.dl.playstation.net
sgst.prod.dl.playstation.net
theia.dl.playstation.net theia.dl.playstation.net
tmdb.np.dl.playstation.net tmdb.np.dl.playstation.net
gs-sec.ww.np.dl.playstation.net
uef.np.dl.playstation.net uef.np.dl.playstation.net
gst.prod.dl.playstation.net
vulcan.dl.playstation.net vulcan.dl.playstation.net
sgst.prod.dl.playstation.net
psnobj.prod.dl.playstation.net

View File

@ -1,6 +1,6 @@
canary.uklans.net
litmus.uklans.net
trigger.uklans.net
canary.lancache.net canary.lancache.net
canary.uklans.net
litmus.lancache.net litmus.lancache.net
litmus.uklans.net
trigger.lancache.net trigger.lancache.net
trigger.uklans.net

View File

@ -1,16 +1,16 @@
dl-wot-ak.wargaming.net
dl-wot-cdx.wargaming.net
dl-wot-gc.wargaming.net
dl-wot-se.wargaming.net
dl-wowp-ak.wargaming.net
dl-wowp-cdx.wargaming.net
dl-wowp-gc.wargaming.net
dl-wowp-se.wargaming.net
dl-wows-ak.wargaming.net
dl-wows-cdx.wargaming.net
dl-wows-gc.wargaming.net
dl-wows-se.wargaming.net
dl2.wargaming.net dl2.wargaming.net
wg.gcdn.co wg.gcdn.co
wgus-wotasia.wargaming.net wgus-wotasia.wargaming.net
dl-wot-ak.wargaming.net
dl-wot-gc.wargaming.net
dl-wot-se.wargaming.net
dl-wot-cdx.wargaming.net
dl-wows-ak.wargaming.net
dl-wows-gc.wargaming.net
dl-wows-se.wargaming.net
dl-wows-cdx.wargaming.net
dl-wowp-ak.wargaming.net
dl-wowp-gc.wargaming.net
dl-wowp-se.wargaming.net
dl-wowp-cdx.wargaming.net
wgus-woteu.wargaming.net wgus-woteu.wargaming.net

View File

@ -1,13 +1,13 @@
*.windowsupdate.com
*.dl.delivery.mp.microsoft.com *.dl.delivery.mp.microsoft.com
dl.delivery.mp.microsoft.com
*.update.microsoft.com
*.do.dsp.mp.microsoft.com *.do.dsp.mp.microsoft.com
*.microsoft.com.edgesuite.net *.microsoft.com.edgesuite.net
*.update.microsoft.com
*.windowsupdate.com
amupdatedl.microsoft.com amupdatedl.microsoft.com
amupdatedl2.microsoft.com amupdatedl2.microsoft.com
amupdatedl3.microsoft.com amupdatedl3.microsoft.com
amupdatedl4.microsoft.com amupdatedl4.microsoft.com
amupdatedl5.microsoft.com amupdatedl5.microsoft.com
dl.delivery.mp.microsoft.com
officecdn.microsoft.com officecdn.microsoft.com
officecdn.microsoft.com.edgesuite.net officecdn.microsoft.com.edgesuite.net

View File

@ -1,7 +1,7 @@
assets1.xboxlive.com assets1.xboxlive.com
assets2.xboxlive.com
xbox-mbr.xboxlive.com
assets1.xboxlive.com.nsatc.net assets1.xboxlive.com.nsatc.net
assets2.xboxlive.com
d1.xboxlive.com
xbox-mbr.xboxlive.com
xvcf1.xboxlive.com xvcf1.xboxlive.com
xvcf2.xboxlive.com xvcf2.xboxlive.com
d1.xboxlive.com