├── find_free_ASN.py ├── LICENSE ├── .gitignore ├── peer_configurator.py └── README.md /find_free_ASN.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | with open('aut-num.txt', 'r', encoding='utf-8') as fin: 5 | s = fin.read() 6 | 7 | l = s.strip().split('\n') 8 | l = [x.strip().replace('AS424242', '') for x in l] 9 | # print(l) 10 | 11 | free_list = [] 12 | for i in range(4000): 13 | n = str(i).rjust(4, '0') 14 | if n not in l: 15 | print(n) 16 | free_list.append(n) 17 | 18 | print('========') 19 | print(free_list) 20 | print(len(free_list)) 21 | 22 | with open('aut-num_free.txt', 'w', encoding='utf-8') as fout: 23 | fout.write(str(free_list)) 24 | 25 | 26 | for i in free_list: 27 | if i[1] == i[2]: 28 | print(i) 29 | 30 | for i in free_list: 31 | if int(i[2]) == int(i[1]) + 1 and int(i[3]) == int(i[2]) + 1: 32 | print(i) 33 | 34 | for i in free_list: 35 | if int(i[2]) == int(i[1]) + 2 and int(i[3]) == int(i[2]) + 2: 36 | print(i) 37 | 38 | for i in free_list: 39 | if i[2] == '8' and i[3] == '8': 40 | print(i) 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 MeowNetwork 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | -------------------------------------------------------------------------------- /peer_configurator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | DN42 peer configurator 5 | DN42 对等连接配置助手 6 | 自动生成 DN42 peer 所需的 WireGuard & BIRD 配置文件并执行 7 | 8 | @Author: MiaoTony 9 | """ 10 | 11 | import os 12 | import time 13 | import sys 14 | 15 | ASN = input('ASNumber: ').strip().replace('AS', '').replace('as', '') 16 | MNT = input('MNT: ').strip() 17 | CONTACT = input('Website/Contact: ').strip() 18 | DATE = time.strftime("%Y%m%d", time.localtime()) 19 | 20 | is_split_v4v6_session = False 21 | is_IPv4_needed = input("Need IPv4 (y/n): ").strip() 22 | if is_IPv4_needed == 'y' or is_IPv4_needed == 'Y': 23 | is_IPv4_needed = True 24 | is_split_v4v6_session = input("Split IPv4 and IPv6 session (y/n): ").strip() 25 | if is_split_v4v6_session == 'y' or is_split_v4v6_session == 'Y': 26 | is_split_v4v6_session = True 27 | else: 28 | is_split_v4v6_session = False 29 | DN42V4 = input('DN42_IPv4: ').strip().split('/')[0] # remove subnet mask 30 | else: 31 | is_IPv4_needed = False 32 | DN42V6 = input('DN42_IPv6/link-local: ').strip().split('/')[0] # remove subnet mask 33 | print() 34 | 35 | print("""====== WireGuard Config ===== 36 | Leave `Endpoint` and `ListenPort` blank if the remote side does not provide a public network address.""") 37 | PublicKey = input('PublicKey: ').strip() 38 | Endpoint = input('Endpoint: ').strip() 39 | ListenPort = input('ListenPort: ').strip() 40 | 41 | wg_config = f""" 42 | # /etc/wireguard/wg_{ASN}.conf 43 | # DN42 AS{ASN} 44 | # {MNT} 45 | # {CONTACT} 46 | # {DATE} 47 | 48 | [Interface] 49 | PrivateKey = REPLACE_PRIVATEKEY_HERE 50 | ListenPort = 2{ASN[-4:]} 51 | """.strip() 52 | 53 | if is_IPv4_needed: 54 | wg_config += f""" 55 | PostUp = ip addr add REPLACE_DN42IPV4_HERE/32 peer {DN42V4}/32 dev %i""" 56 | 57 | if DN42V6.startswith('fe80'): 58 | # link-local 59 | wg_config += f""" 60 | PostUp = ip addr add REPLACE_LINKLOCALIPV6_HERE/64 dev %i""" 61 | else: 62 | wg_config += f""" 63 | PostUp = ip addr add REPLACE_DN42IPV6_HERE/128 peer {DN42V6}/128 dev %i""" 64 | 65 | wg_config += f""" 66 | Table = off 67 | 68 | [Peer] 69 | PublicKey = {PublicKey}""" 70 | if Endpoint and ListenPort: 71 | wg_config += f""" 72 | Endpoint = {Endpoint}:{ListenPort}""" 73 | wg_config +=""" 74 | AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe80::/64 75 | """ 76 | 77 | 78 | if is_split_v4v6_session: 79 | bird_config = f""" 80 | # /etc/bird/peers/AS{ASN}.conf 81 | # DN42 AS{ASN} 82 | # {MNT} 83 | # {CONTACT} 84 | # {DATE} 85 | 86 | protocol bgp dn42_{ASN}_v6 from dnpeers {{ 87 | neighbor {DN42V6} % 'wg_{ASN}' as {ASN}; 88 | direct; 89 | ipv4 {{ 90 | import none; 91 | export none; 92 | }}; 93 | }} 94 | 95 | protocol bgp dn42_{ASN}_v4 from dnpeers {{ 96 | neighbor {DN42V4} % 'wg_{ASN}' as {ASN}; 97 | direct; 98 | ipv6 {{ 99 | import none; 100 | export none; 101 | }}; 102 | }} 103 | """.strip() 104 | else: 105 | bird_config = f""" 106 | # /etc/bird/peers/AS{ASN}.conf 107 | # DN42 AS{ASN} 108 | # {MNT} 109 | # {CONTACT} 110 | # {DATE} 111 | 112 | protocol bgp dn42_{ASN}_v6 from dnpeers {{ 113 | neighbor {DN42V6} % 'wg_{ASN}' as {ASN}; 114 | direct; 115 | }} 116 | """.strip() 117 | 118 | 119 | print("\n####### WireGuard Info #######\n") 120 | print(wg_config) 121 | 122 | print("\n####### BIRD Info #######\n") 123 | print(bird_config) 124 | print() 125 | 126 | while True: 127 | choice = input("##### Is everything OK (y/n): ").strip() 128 | if choice == 'y' or choice == 'Y': 129 | break 130 | elif choice == 'n' or choice == 'N': 131 | sys.exit(1) 132 | 133 | print("\n##### Write WireGuard config...") 134 | with open(f"/etc/wireguard/wg_{ASN}.conf", 'w', encoding='utf-8') as f_wg: 135 | f_wg.write(wg_config) 136 | 137 | print("\n##### Write BIRD config...") 138 | with open(f"/etc/bird/peers/AS{ASN}.conf", 'w', encoding='utf-8') as f_bird: 139 | f_bird.write(bird_config) 140 | 141 | print("\n##### Write OK! #####") 142 | 143 | print("\n##### Generate WireGuard connection...") 144 | os.system(f"systemctl enable wg-quick@wg_{ASN}.service && service wg-quick@wg_{ASN} start") 145 | 146 | print("\n##### Reconfigure BIRD...") 147 | os.system("birdc c") 148 | print('====================================================\n') 149 | 150 | time.sleep(5) 151 | print(f'-----> wg show wg_{ASN}') 152 | os.system(f"wg show wg_{ASN}") 153 | print('----------------------------------------------------') 154 | print(f'-----> birdc s p all dn42_{ASN}_v6') 155 | os.system(f"birdc s p all dn42_{ASN}_v6") 156 | if is_split_v4v6_session: 157 | print(f'-----> birdc s p all dn42_{ASN}_v4') 158 | os.system(f"birdc s p all dn42_{ASN}_v4") 159 | 160 | print("\n##### Everything is OK!") 161 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MeowDN42wheels 2 | 3 | Some tools for MiaoTony's DN42 Network, aka MeowNet / MeowNetwork 4 | 5 | ***喵喵又在造轮子啦!*** 6 | 7 | # DN42 Free ASN Finder 8 | 9 | `find_free_ASN.py` 用于查询空闲未被使用的 ASN,你可以自己改代码挑选你喜欢的编号。 10 | 11 | 你需要先 clone https://git.dn42.dev/dn42/registry 然后列出 `data/aut-num/` 文件夹下的文件到 `aut-num.txt` 12 | 13 | ```bash 14 | git clone git@git.dn42.dev:/registry.git 15 | # Where is your gitea username. 16 | ls -1 registry/data/aut-num/ > aut-num.txt 17 | python3 find_free_ASN.py 18 | ``` 19 | 20 | 21 | # DN42 Peer Configurator 22 | 23 | `peer_configurator.py` 是一个自动化脚本,用于在 DN42 网络中快速配置和建立对等连接(peer)。 24 | 25 | 只用输入对方的连接信息,该脚本就会生成必要的 WireGuard VPN 和 BIRD 路由配置文件,而后自动完成配置,并展示新建立的连接情况,从而大大简化了整个 peer 过程,同时降低了手工配置而引入的出错风险。 26 | 27 | An automated script used to quickly configure and establish peer-to-peer connections in a DN42 network. 28 | 29 | This script will generate the necessary WireGuard VPN and BIRD routing configurations and complete them, greatly simplifying the entire peer process and reducing the risk of errors introduced by manual configuration. 30 | 31 | ## 环境要求 / Environmental requirements 32 | - Linux 33 | - WireGuard & BIRD (with systemd) 34 | - Python (Python 3.6 or higher is recommended), no additional dependencies need to be installed 35 | 36 | ## 使用步骤 / Steps 37 | ### Step1: 下载脚本 Download the script 38 | 首先,将 `peer_configurator.py` 脚本下载到您的服务器上。您可以使用喜欢的方式来下载。 39 | 40 | ```bash 41 | wget https://github.com/MeowNetwork/MeowDN42wheels/raw/master/peer_configurator.py 42 | # OR 43 | # curl -LO https://github.com/MeowNetwork/MeowDN42wheels/raw/master/peer_configurator.py 44 | ``` 45 | 46 | 或者 47 | 48 | ```bash 49 | git clone https://github.com/MeowNetwork/MeowDN42wheels.git 50 | cd MeowDN42wheels 51 | ``` 52 | 53 | ### Step2: 修改您的配置信息后运行脚本 Modify your information and run the script 54 | 55 | 把自己的信息配置好,下面依次是自己的 WireGuard 私钥、DN42 IPv4、DN42 IPv6、link-local IPv6 56 | *(假设 `xxxxxxxxxxxxxxxxxxxxx`、`172.23.45.67`、`fd00:dead:beaf::1234`、`fe80::1234` 是你的)* 57 | 58 | Configure your own information, below are your WireGuard private key, DN42 IPv4, DN42 IPv6, and link local IPv6 in order. 59 | *(Assuming `xxxxxxxxxxxxxxxxxxxxx`, `172.23.45.67`, `fd00:dead:beaf::1234`, `fe80::1234` are yours)* 60 | 61 | ```bash 62 | sed -i -e 's#REPLACE_PRIVATEKEY_HERE#xxxxxxxxxxxxxxxxxxxxx#g' -e 's#REPLACE_DN42IPV4_HERE#172.23.45.67#g' -e 's#REPLACE_DN42IPV6_HERE#fd00:dead:beaf::1234#g' -e 's#REPLACE_LINKLOCALIPV6_HERE#fe80::1234#g' peer_configurator.py 63 | ``` 64 | 65 | 在执行脚本之前,请确保您具有 root 执行权限。 66 | Ensure that you have root privileges. 67 | 68 | ```bash 69 | sudo python3 peer_configurator.py 70 | ``` 71 | 72 | ### Step 3: 输入配置信息 Enter configuration information 73 | 74 | 首先配置对方联系信息: 75 | Configure your peer's contact information: 76 | 77 | - **ASNumber**: 对方的 DN42 自治系统号(AS号),可以直接输入 `424242xxxx` 或者 `AS424242xxxx` 78 | Your peer's DN42 autonomous system number (AS number), e.g. `424242xxxx`, `AS424242xxxx` 79 | - **MNT**: 对方的维护者标识 80 | Your peer's maintainer 81 | - **Website/Contact**: *(可选)* 对方的联系信息(网站/电子邮件/Telegram/etc.),便于出问题时联系对方 82 | *(Optional)* Contact information of your peer (website/email/Telegram/etc.), to facilitate contacting the peer in case of problems 83 | 84 | 接下来是具体的 IP 配置部分: 85 | 86 | - **IPv4 Configuration**: 询问是否需要 DN42 IPv4 配置。如果需要,请输入 `y`,并根据后续提示输入 IPv4 地址,否则 `n`。如果支持 Extended Next Hop(需要 BIRD 2.0.8+ 且手动开启),那么可以输入 `n` 省略此项配置。 87 | Ask if DN42 IPv4 configuration is needed. If so, enter `y` and follow prompts to input the IPv4 address. If it supports Extended Next Hop (requires BIRD 2.0.8+ and manual activation), you can just enter `n` to omit this configuration. 88 | - **DN42_IPv4**: 仅当需要 IPv4 时输入。输入对方的 DN42 IPv4 地址,这将附加在新建立的 WireGuard 网卡上。 89 | Enter only if IPv4 is needed. Input your peer's DN42 IPv4 address, which will be attached to the newly established WireGuard device. 90 | - **Split IPv4 and IPv6 session**: 询问是否需要将 IPv4 和 IPv6 会话分开。如果需要,请输入 `y`,将为 v4 和 v6 分别建立单独的会话,且在路由传递禁用另一协议,不需要请输入 `n` 91 | Ask if IPv4 and IPv6 sessions should be split. Enter `y` if required, then separate sessions will be established for v4 and v6 respectively, and the other protocol will be disabled during routing delivery. 92 | - **DN42_IPv6/link-local**:对方的 DN42 IPv6 或本地链路地址 93 | Input your peer's DN42 IPv6 or link-local address. 94 | 95 | 一般而言,MeowNetwork (AS4242422688) 及很多其他的 DN42 网络通常与对方使用 link-local IPv6 地址来建立 Multiprotocol-BGP ([RFC 5549](https://www.rfc-editor.org/info/rfc5549)) v4+v6 channels(只需要建立一个 IPv6 会话),并开启 Extended Next Hop,则上面 **输入两次 `n` 后使用形如 `fe80::<对方ASN后4位>` 的地址来建立 peer 即可** 96 | 97 | Generally, MeowNetwork (AS4242422688) and many other DN42 networks typically use link-local IPv6 addresses to establish Multiprotocol-BGP ([RFC 5549](https://www.rfc-editor.org/info/rfc5549)) v4+v6 channels with the peer (just need to establish an IPv6 session) and enable Extended Next Hop. To establish a peer, just enter `n` twice and use an address similar to `fe80::`. 98 | 99 | 接下来是 **WireGuard 配置**: 100 | 101 | - **PublicKey**: 输入对方的 WireGuard 公钥 102 | your peer's WireGuard public key 103 | - **Endpoint**: 对方的地址,可以是域名或者公网 IP 地址 104 | Your peer's hostname or public IP address 105 | - **ListenPort**: 对方 WireGuard 监听的端口号 106 | the port number on which your peer's WireGuard listens 107 | 108 | 如果对端未提供公网地址,将 `Endpoint` 和 `ListenPort` 留空即可。 109 | If your peer does not provide a public address, just leave `Endpoint` and `ListenPort` blank. 110 | 111 | 请注意,本脚本将使用 `20000 + 对方ASN后4位` 作为本机 WireGuard 监听的端口号 112 | Please note that this script will use `20000 + the last 4 digits of your peer's ASN` as the port for local WireGuard listening. 113 | 114 | 115 | ### Step4: 确认配置文件并完成配置 Confirmation 116 | 脚本会显示生成的 WireGuard 和 BIRD 配置信息预览。请仔细检查这些信息是否正确。 117 | 118 | 确认(输入`y`)后脚本将自动写入并执行配置,其中已配置开机自启 119 | 120 | 请确保使用 systemd 管理 WireGuard 及 BIRD daemon,否则可能配置失败,您可以手动完成最后的启动流程 121 | 122 | Preview of the generated WireGuard and BIRD configuration information will be displayed. Please carefully check if this information is correct. 123 | 124 | After confirmation (input `y`), the script will automatically write and execute the configuration, where the startup self start has been configured. 125 | 126 | Please ensure to use Systemd to manage WireGuard and BIRD daemons, otherwise configuration may fail. You can manually complete the final startup process. 127 | 128 | 脚本将自动展示新建立的 peer 的 WireGuard 及 BIRD 连接情况 129 | 130 | The WireGuard and BIRD connection status of the newly established peer will be displayed. 131 | 132 | 133 | ## Sponsorship 134 | 135 | 非常高兴能帮到你,欢迎点个 star,也可以 [给喵喵投喂](https://miaotony.xyz/about/#Sponsorship)! *(仰望.jpg* 136 | 137 | *[Buy me a cup of coffee~](https://miaotony.xyz/about/#Sponsorship)* 138 | 139 | 140 | 141 | ## Copyright 142 | 143 | **本项目仅供学习研究使用,请在合理合法范围内使用!** 144 | **The relevant technical content of this project is only for study and research, please use within the reasonable and legal scope!** 145 | 146 | License: 147 | [MIT License](LICENSE) 148 | 149 | 最终解释权归本项目开发者所有。 150 | The final interpretation right belongs to the developer of the project. 151 | 152 | Copyright © 2023-2025 [MiaoTony](https://github.com/miaotony). 153 | --------------------------------------------------------------------------------