Commit d487d863 authored by nanahira's avatar nanahira

Merge branch 'master' into gwgroup

parents d43533a5 08cdb9e0
......@@ -113,6 +113,6 @@ dist
/build
*.retry
*-setconf.conf.j2
wgfrp-setconf.conf.j2
__pycache__
......@@ -2,3 +2,12 @@
become: true
roles:
- 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 @@
src: wg-setconf.conf.j2
dest: '/tmp/{{conn.name}}-setconf.conf'
register: 'wg_setconf_result'
when: 'not wg_enable_result.changed and not wg_conf_result.changed'
ignore_errors: true
- name: '{{conn.name}}: wg setconf'
become: true
ignore_errors: true
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={{
[Peer]
PublicKey = {{conn.wgPublicKey}}
AllowedIPs = 0.0.0.0/0, ::/0
{% if conn.remoteAddress is defined %}
{% if conn.remoteAddress %}
Endpoint = {{conn.remoteAddress}}:{{conn.remotePort}}
PersistentKeepalive = 1
{% endif %}
......
......@@ -35,8 +35,9 @@
src: wgfrp-setconf.conf.j2
dest: '/tmp/{{conn.name}}-setconf.conf'
register: 'wg_setconf_result'
when: 'not wg_enable_result.changed and not wg_conf_result.changed'
- name: '{{conn.name}}: wg setconf'
become: true
ignore_errors: true
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 @@
- name: 安装软件包 (apt)
become: true
apt:
name: wireguard
name: wireguard,ipset
update_cache: yes
when: ansible_os_family == 'Debian'
- name: WireGuard 源 (CentOS)
......@@ -25,7 +25,7 @@
yum:
state: latest
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"
- name: epel 8
become: true
......@@ -37,7 +37,7 @@
become: true
dnf:
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"
- name: config directories
file:
......
......@@ -16,7 +16,7 @@ ip rule add pref 81 to {{subnet}} lookup main || true
# chain for wg 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 -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
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
......@@ -7,12 +7,46 @@ import _ from 'lodash';
import child_process from 'child_process';
import assert from 'assert';
import ip from "ip";
import { promises as dns } from "dns";
class InventoryBuilder {
hosts: { [key: string]: any };
gateways: any;
connections: string[];
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) {
const data = await fs.promises.readFile(path.join('data', `内网互联计划 - ${sheetName}.csv`));
......@@ -23,6 +57,7 @@ class InventoryBuilder {
async loadGateways() {
const gateways = await this.load('gateways2');
for (let gateway of gateways) {
gateway.isCN = this.hosts[gateway.router] && this.hosts[gateway.router].location.startsWith("CN");
if (gateway.mark) {
gateway.selectionMark = gateway.mark + 50;
} else {
......@@ -43,7 +78,7 @@ class InventoryBuilder {
host.wgPublickey = await this.wgPublickey(host.wgPrivateKey);
}
// 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);
// console.log(hosts);
const vars = await this.loadUtilities();
......@@ -83,7 +118,7 @@ class InventoryBuilder {
return vars;
}
host_vars(host) {
async host_vars(host) {
const connections = [];
host.dockerServices = {
version: '2.4',
......@@ -107,17 +142,17 @@ class InventoryBuilder {
const from = this.hosts[h][host.name]; // 其他主机的这个主机的条目
if (from && to) {
// 非对称连接
connections.push(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], to, false, true, false));
connections.push(await this.parse_connection(host, this.hosts[h], from, true, false, true));
} else if (from || to) {
// 对称连接
const connectionString = from || to;
connections.push(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], connectionString, true, true, connectionString === from));
connections.push(await this.parse_connection(host, this.hosts[h], null_connection, false, false, false));
} else {
// 不连接
connections.push(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, true, false, false));
connections.push(await this.parse_connection(host, this.hosts[h], null_connection, false, true, false));
}
routePlans.push({
name: h.replace(/-/g, "_"),
......@@ -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 cis = !reverse; // true 无需翻转,false 需要翻转。
const primary = leftbottom ? outbound : inbound; // true 使用 peerAddress、port, false 使用peerAddress2、port2
......@@ -163,7 +198,8 @@ class InventoryBuilder {
const remoteGateway = remoteGatewayName ? this.gateways[remote.name][remoteGatewayName] : _.find(this.gateways[remote.name]);
//const remoteGatewayMark = remoteGatewayName ? remoteGateway.mark : undefined;
//console.log(remoteGateway.name);
const remoteAddress = remoteGateway.address;
const remoteAddress = remoteGateway.address || null;
const resolvedRemoteAddress = await this.resolveDomain(remoteAddress);
const remoteLocalAddress = remote.address;
const remoteNextMark = remote.nextMark;
const remoteDestMark = remote.destMark;
......@@ -202,7 +238,7 @@ class InventoryBuilder {
//console.log(local.name, name, mtu);
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 {
......@@ -214,6 +250,7 @@ class InventoryBuilder {
remoteNextMark,
remoteDestMark,
remoteAddress,
resolvedRemoteAddress,
remoteLocalAddress,
localPort,
remotePort,
......@@ -231,21 +268,23 @@ class InventoryBuilder {
// frps还是frpc的积分,NAT越有利分越高
gatewayCompareScore(gateway: any): number {
let score: number = 0xff - gateway.id;
const ipv4Score = ({
"static": 2,
"dynamic": 1
})[gateway.ipv4] || 0;
score |= ipv4Score << 12;
const ipv4NatScore = ({
let score: number = 0xff - gateway.id; // 8 bits
const isCNScore = gateway.isCN ? 0 : 1; // 1 bit
score |= isCNScore << 8;
const ipv4NatScore = ({ // 2 bits
"ports": 0,
"dmz": 1
})[gateway.ipv4Nat] || 2;
score |= ipv4NatScore << 10;
const globalSSHScore = ({
score |= ipv4NatScore << 9;
const ipv4Score = ({ // 2 bits
"static": 2,
"dynamic": 1
})[gateway.ipv4] || 0;
score |= ipv4Score << 11;
const globalSSHScore = ({ // 1 bit
"globalssh": 1
})[gateway.ssh] || 0;
score |= globalSSHScore << 13;
score |= globalSSHScore << 12;
return score;
}
......
......@@ -8,11 +8,12 @@ set -e
mkdir -p result
npm run build
npm start
#cd lists
#./run.sh
#cd ..
cd lists
./run.sh
cd ..
cd ansible || exit
......@@ -24,7 +25,7 @@ _strip_wg_conf() {
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
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