Commit d487d863 authored by nanahira's avatar nanahira

Merge branch 'master' into gwgroup

parents d43533a5 08cdb9e0
...@@ -113,6 +113,6 @@ dist ...@@ -113,6 +113,6 @@ dist
/build /build
*.retry *.retry
*-setconf.conf.j2 wgfrp-setconf.conf.j2
__pycache__ __pycache__
...@@ -2,3 +2,12 @@ ...@@ -2,3 +2,12 @@
become: true become: true
roles: roles:
- wireguard - wireguard
tasks:
- name: pull images
docker_image:
name: '{{item}}'
source: pull
with_items:
- fatedier/frps:v0.34.2
- fatedier/frpc:v0.34.2
- git-registry.mycard.moe/nanahira/docker-bird
...@@ -27,9 +27,10 @@ ...@@ -27,9 +27,10 @@
src: wg-setconf.conf.j2 src: wg-setconf.conf.j2
dest: '/tmp/{{conn.name}}-setconf.conf' dest: '/tmp/{{conn.name}}-setconf.conf'
register: 'wg_setconf_result' register: 'wg_setconf_result'
when: 'not wg_enable_result.changed and not wg_conf_result.changed'
ignore_errors: true ignore_errors: true
- name: '{{conn.name}}: wg setconf' - name: '{{conn.name}}: wg setconf'
become: true become: true
ignore_errors: true ignore_errors: true
shell: 'wg setconf {{conn.name}} /tmp/{{conn.name}}-setconf.conf' shell: 'wg setconf {{conn.name}} /tmp/{{conn.name}}-setconf.conf'
when: 'wg_setconf_result.changed' when: 'not wg_enable_result.changed and not wg_conf_result.changed and wg_setconf_result.changed'
[Interface]
PrivateKey = {{key}}
ListenPort = {{conn.localPort}}
{% if conn.localGatewayMark != 0 %}
FwMark = {{conn.localGatewayMark}}
{% endif %}
[Peer]
PublicKey = {{conn.wgPublicKey}}
AllowedIPs = 0.0.0.0/0, ::/0
{% if conn.resolvedRemoteAddress %}
Endpoint = {{conn.resolvedRemoteAddress}}:{{conn.remotePort}}
PersistentKeepalive = 1
{% endif %}
# forced change 12.12
...@@ -14,7 +14,7 @@ PreDown = dev=%i localPeerAddress={{conn.localPeerAddress}} remotePeerAddress={{ ...@@ -14,7 +14,7 @@ PreDown = dev=%i localPeerAddress={{conn.localPeerAddress}} remotePeerAddress={{
[Peer] [Peer]
PublicKey = {{conn.wgPublicKey}} PublicKey = {{conn.wgPublicKey}}
AllowedIPs = 0.0.0.0/0, ::/0 AllowedIPs = 0.0.0.0/0, ::/0
{% if conn.remoteAddress is defined %} {% if conn.remoteAddress %}
Endpoint = {{conn.remoteAddress}}:{{conn.remotePort}} Endpoint = {{conn.remoteAddress}}:{{conn.remotePort}}
PersistentKeepalive = 1 PersistentKeepalive = 1
{% endif %} {% endif %}
......
...@@ -35,8 +35,9 @@ ...@@ -35,8 +35,9 @@
src: wgfrp-setconf.conf.j2 src: wgfrp-setconf.conf.j2
dest: '/tmp/{{conn.name}}-setconf.conf' dest: '/tmp/{{conn.name}}-setconf.conf'
register: 'wg_setconf_result' register: 'wg_setconf_result'
when: 'not wg_enable_result.changed and not wg_conf_result.changed'
- name: '{{conn.name}}: wg setconf' - name: '{{conn.name}}: wg setconf'
become: true become: true
ignore_errors: true ignore_errors: true
shell: 'wg setconf {{conn.name}} /tmp/{{conn.name}}-setconf.conf' shell: 'wg setconf {{conn.name}} /tmp/{{conn.name}}-setconf.conf'
when: 'wg_setconf_result.changed' when: 'not wg_enable_result.changed and not wg_conf_result.changed and wg_setconf_result.changed'
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
- name: 安装软件包 (apt) - name: 安装软件包 (apt)
become: true become: true
apt: apt:
name: wireguard name: wireguard,ipset
update_cache: yes update_cache: yes
when: ansible_os_family == 'Debian' when: ansible_os_family == 'Debian'
- name: WireGuard 源 (CentOS) - name: WireGuard 源 (CentOS)
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
yum: yum:
state: latest state: latest
update_cache: true update_cache: true
name: wireguard-tools,wireguard-dkms name: wireguard-tools,wireguard-dkms,ipset
when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version|int <= 7" when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version|int <= 7"
- name: epel 8 - name: epel 8
become: true become: true
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
become: true become: true
dnf: dnf:
state: latest state: latest
name: wireguard-tools,wireguard-dkms name: wireguard-tools,wireguard-dkms,ipset
when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version|int == 8" when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version|int == 8"
- name: config directories - name: config directories
file: file:
......
...@@ -16,7 +16,7 @@ ip rule add pref 81 to {{subnet}} lookup main || true ...@@ -16,7 +16,7 @@ ip rule add pref 81 to {{subnet}} lookup main || true
# chain for wg origin # chain for wg origin
iptables -t mangle -N NEXTGEN_ORIGIN iptables -t mangle -N NEXTGEN_ORIGIN
iptables -t mangle -A PREROUTING -m mark --mark 0x0 ! -p ospf -j NEXTGEN_ORIGIN iptables -t mangle -I PREROUTING -m mark --mark 0x0 ! -p ospf -j NEXTGEN_ORIGIN
iptables -t mangle -N NEXTGEN_SWITCH iptables -t mangle -N NEXTGEN_SWITCH
iptables -t mangle -A PREROUTING -m mark --mark 0x0 ! -p ospf -m set ! --match-set mycard dst -j NEXTGEN_SWITCH iptables -t mangle -A PREROUTING -m mark --mark 0x0 ! -p ospf -m set ! --match-set mycard dst -j NEXTGEN_SWITCH
......
...@@ -3,4 +3,15 @@ source {{ansible_user_dir}}/nextgen-network/scripts/utility.sh ...@@ -3,4 +3,15 @@ source {{ansible_user_dir}}/nextgen-network/scripts/utility.sh
iptables -t mangle -F NEXTGEN_SWITCH iptables -t mangle -F NEXTGEN_SWITCH
## restore mark
{% for plan in routePlans %}
ip rule del pref 400 fwmark {{plan.destMark}} lookup {{plan.destMark}}
restore_mark_switch -D {{plan.destMark}}
{% endfor %}
{% for gw in gateways %}
{% if gw.selectionMark > 0 %}
restore_mark_switch -D {{gw.selectionMark}}
{% endif %}
{% endfor %}
true true
...@@ -7,12 +7,46 @@ import _ from 'lodash'; ...@@ -7,12 +7,46 @@ import _ from 'lodash';
import child_process from 'child_process'; import child_process from 'child_process';
import assert from 'assert'; import assert from 'assert';
import ip from "ip"; import ip from "ip";
import { promises as dns } from "dns";
class InventoryBuilder { class InventoryBuilder {
hosts: { [key: string]: any }; hosts: { [key: string]: any };
gateways: any; gateways: any;
connections: string[]; connections: string[];
routeLists: any; routeLists: any;
resolveCache: Map<string, string>;
resolver: dns.Resolver;
async resolveDomain(domain: string) {
if (!domain || domain.match(/(\d{1,3}\.){3}\d{1,3}/)) {
return domain;
}
if (this.resolveCache.has(domain)) {
return this.resolveCache.get(domain);
}
const rrtype = domain.includes("-v6") ? "AAAA" : "A";
let resolvedIP: string;
while (true) {
try {
[ resolvedIP ] = (await this.resolver.resolve(domain, rrtype)) as string[];
break;
} catch (e) {
console.log(`${domain} => FAIL: ${e.toString()}`);
}
}
if (rrtype === "AAAA") {
resolvedIP = `[${resolvedIP}]`;
}
console.log(`${domain} => ${resolvedIP}`);
this.resolveCache.set(domain, resolvedIP);
return resolvedIP;
}
constructor() {
this.resolveCache = new Map();
this.resolver = new dns.Resolver();
this.resolver.setServers(['114.114.114.114', '223.5.5.5']);
}
async load(sheetName) { async load(sheetName) {
const data = await fs.promises.readFile(path.join('data', `内网互联计划 - ${sheetName}.csv`)); const data = await fs.promises.readFile(path.join('data', `内网互联计划 - ${sheetName}.csv`));
...@@ -23,6 +57,7 @@ class InventoryBuilder { ...@@ -23,6 +57,7 @@ class InventoryBuilder {
async loadGateways() { async loadGateways() {
const gateways = await this.load('gateways2'); const gateways = await this.load('gateways2');
for (let gateway of gateways) { for (let gateway of gateways) {
gateway.isCN = this.hosts[gateway.router] && this.hosts[gateway.router].location.startsWith("CN");
if (gateway.mark) { if (gateway.mark) {
gateway.selectionMark = gateway.mark + 50; gateway.selectionMark = gateway.mark + 50;
} else { } else {
...@@ -43,7 +78,7 @@ class InventoryBuilder { ...@@ -43,7 +78,7 @@ class InventoryBuilder {
host.wgPublickey = await this.wgPublickey(host.wgPrivateKey); host.wgPublickey = await this.wgPublickey(host.wgPrivateKey);
} }
// console.log(Object.values(this.hosts)); // console.log(Object.values(this.hosts));
const rawHosts = Object.values(this.hosts).map(h => [h.name, this.host_vars(h)]); const rawHosts = await Promise.all(Object.values(this.hosts).map(async(h) => [h.name, await this.host_vars(h)]));
const hosts = Object.fromEntries(rawHosts); const hosts = Object.fromEntries(rawHosts);
// console.log(hosts); // console.log(hosts);
const vars = await this.loadUtilities(); const vars = await this.loadUtilities();
...@@ -83,7 +118,7 @@ class InventoryBuilder { ...@@ -83,7 +118,7 @@ class InventoryBuilder {
return vars; return vars;
} }
host_vars(host) { async host_vars(host) {
const connections = []; const connections = [];
host.dockerServices = { host.dockerServices = {
version: '2.4', version: '2.4',
...@@ -107,17 +142,17 @@ class InventoryBuilder { ...@@ -107,17 +142,17 @@ class InventoryBuilder {
const from = this.hosts[h][host.name]; // 其他主机的这个主机的条目 const from = this.hosts[h][host.name]; // 其他主机的这个主机的条目
if (from && to) { if (from && to) {
// 非对称连接 // 非对称连接
connections.push(this.parse_connection(host, this.hosts[h], to, false, true, false)); connections.push(await this.parse_connection(host, this.hosts[h], to, false, true, false));
connections.push(this.parse_connection(host, this.hosts[h], from, true, false, true)); connections.push(await this.parse_connection(host, this.hosts[h], from, true, false, true));
} else if (from || to) { } else if (from || to) {
// 对称连接 // 对称连接
const connectionString = from || to; const connectionString = from || to;
connections.push(this.parse_connection(host, this.hosts[h], connectionString, true, true, connectionString === from)); connections.push(await this.parse_connection(host, this.hosts[h], connectionString, true, true, connectionString === from));
connections.push(this.parse_connection(host, this.hosts[h], null_connection, false, false, false)); connections.push(await this.parse_connection(host, this.hosts[h], null_connection, false, false, false));
} else { } else {
// 不连接 // 不连接
connections.push(this.parse_connection(host, this.hosts[h], null_connection, true, false, false)); connections.push(await this.parse_connection(host, this.hosts[h], null_connection, true, false, false));
connections.push(this.parse_connection(host, this.hosts[h], null_connection, false, true, false)); connections.push(await this.parse_connection(host, this.hosts[h], null_connection, false, true, false));
} }
routePlans.push({ routePlans.push({
name: h.replace(/-/g, "_"), name: h.replace(/-/g, "_"),
...@@ -145,7 +180,7 @@ class InventoryBuilder { ...@@ -145,7 +180,7 @@ class InventoryBuilder {
}; };
} }
parse_connection(local: any, remote: any, connstr: string, inbound: boolean, outbound: boolean, reverse: boolean) { async parse_connection(local: any, remote: any, connstr: string, inbound: boolean, outbound: boolean, reverse: boolean) {
const leftbottom = local.id > remote.id; // true 条目位于左下,false 条目位于右上 const leftbottom = local.id > remote.id; // true 条目位于左下,false 条目位于右上
const cis = !reverse; // true 无需翻转,false 需要翻转。 const cis = !reverse; // true 无需翻转,false 需要翻转。
const primary = leftbottom ? outbound : inbound; // true 使用 peerAddress、port, false 使用peerAddress2、port2 const primary = leftbottom ? outbound : inbound; // true 使用 peerAddress、port, false 使用peerAddress2、port2
...@@ -163,7 +198,8 @@ class InventoryBuilder { ...@@ -163,7 +198,8 @@ class InventoryBuilder {
const remoteGateway = remoteGatewayName ? this.gateways[remote.name][remoteGatewayName] : _.find(this.gateways[remote.name]); const remoteGateway = remoteGatewayName ? this.gateways[remote.name][remoteGatewayName] : _.find(this.gateways[remote.name]);
//const remoteGatewayMark = remoteGatewayName ? remoteGateway.mark : undefined; //const remoteGatewayMark = remoteGatewayName ? remoteGateway.mark : undefined;
//console.log(remoteGateway.name); //console.log(remoteGateway.name);
const remoteAddress = remoteGateway.address; const remoteAddress = remoteGateway.address || null;
const resolvedRemoteAddress = await this.resolveDomain(remoteAddress);
const remoteLocalAddress = remote.address; const remoteLocalAddress = remote.address;
const remoteNextMark = remote.nextMark; const remoteNextMark = remote.nextMark;
const remoteDestMark = remote.destMark; const remoteDestMark = remote.destMark;
...@@ -202,7 +238,7 @@ class InventoryBuilder { ...@@ -202,7 +238,7 @@ class InventoryBuilder {
//console.log(local.name, name, mtu); //console.log(local.name, name, mtu);
if (outbound) { if (outbound) {
console.log(`${local.name} GW ${localGateway.isp} ${inbound ? "<" : "="}==[${protocol}]==> ${remote.name} GW ${remoteGateway.isp}`); console.log(`${local.name} GW ${localGateway.isp} ${inbound ? "<" : "="}=${frpType === "frps" ? "s" : "="}=[${protocol}]=${frpType === "frpc" ? "s" : "="}=> ${remote.name} GW ${remoteGateway.isp}`);
} }
return { return {
...@@ -214,6 +250,7 @@ class InventoryBuilder { ...@@ -214,6 +250,7 @@ class InventoryBuilder {
remoteNextMark, remoteNextMark,
remoteDestMark, remoteDestMark,
remoteAddress, remoteAddress,
resolvedRemoteAddress,
remoteLocalAddress, remoteLocalAddress,
localPort, localPort,
remotePort, remotePort,
...@@ -231,21 +268,23 @@ class InventoryBuilder { ...@@ -231,21 +268,23 @@ class InventoryBuilder {
// frps还是frpc的积分,NAT越有利分越高 // frps还是frpc的积分,NAT越有利分越高
gatewayCompareScore(gateway: any): number { gatewayCompareScore(gateway: any): number {
let score: number = 0xff - gateway.id; let score: number = 0xff - gateway.id; // 8 bits
const ipv4Score = ({ const isCNScore = gateway.isCN ? 0 : 1; // 1 bit
"static": 2, score |= isCNScore << 8;
"dynamic": 1 const ipv4NatScore = ({ // 2 bits
})[gateway.ipv4] || 0;
score |= ipv4Score << 12;
const ipv4NatScore = ({
"ports": 0, "ports": 0,
"dmz": 1 "dmz": 1
})[gateway.ipv4Nat] || 2; })[gateway.ipv4Nat] || 2;
score |= ipv4NatScore << 10; score |= ipv4NatScore << 9;
const globalSSHScore = ({ const ipv4Score = ({ // 2 bits
"static": 2,
"dynamic": 1
})[gateway.ipv4] || 0;
score |= ipv4Score << 11;
const globalSSHScore = ({ // 1 bit
"globalssh": 1 "globalssh": 1
})[gateway.ssh] || 0; })[gateway.ssh] || 0;
score |= globalSSHScore << 13; score |= globalSSHScore << 12;
return score; return score;
} }
......
...@@ -8,11 +8,12 @@ set -e ...@@ -8,11 +8,12 @@ set -e
mkdir -p result mkdir -p result
npm run build
npm start npm start
#cd lists cd lists
#./run.sh ./run.sh
#cd .. cd ..
cd ansible || exit cd ansible || exit
...@@ -24,7 +25,7 @@ _strip_wg_conf() { ...@@ -24,7 +25,7 @@ _strip_wg_conf() {
wg-quick strip $tmpFileName > $targetPath wg-quick strip $tmpFileName > $targetPath
} }
_strip_wg_conf ./protocols/wg/wg.conf.j2 ./protocols/wg/wg-setconf.conf.j2 # _strip_wg_conf ./protocols/wg/wg.conf.j2 ./protocols/wg/wg-setconf.conf.j2
_strip_wg_conf ./protocols/wgfrp/wgfrp.conf.j2 ./protocols/wgfrp/wgfrp-setconf.conf.j2 _strip_wg_conf ./protocols/wgfrp/wgfrp.conf.j2 ./protocols/wgfrp/wgfrp-setconf.conf.j2
ansible-playbook -i ../result/inventory.yaml "$@" configure.yaml ansible-playbook -i ../result/inventory.yaml "$@" configure.yaml
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment