Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
T
tun
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Railgun
tun
Commits
2d543899
Commit
2d543899
authored
Dec 18, 2020
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ts part
parent
4826c896
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
141 additions
and
9 deletions
+141
-9
.gitignore
.gitignore
+1
-0
ansible/protocols/oc/configure.yaml
ansible/protocols/oc/configure.yaml
+8
-0
ansible/protocols/oc/ocserv-per-user.conf.j2
ansible/protocols/oc/ocserv-per-user.conf.j2
+2
-0
ansible/protocols/oc/ocserv-pre.yaml
ansible/protocols/oc/ocserv-pre.yaml
+0
-0
ansible/protocols/oc/ocserv.conf.j2
ansible/protocols/oc/ocserv.conf.j2
+42
-0
ansible/protocols/oc/openconnect-postdown.sh.j2
ansible/protocols/oc/openconnect-postdown.sh.j2
+2
-0
ansible/protocols/oc/openconnect-postup.sh.j2
ansible/protocols/oc/openconnect-postup.sh.j2
+2
-0
src/inventory.ts
src/inventory.ts
+84
-9
No files found.
.gitignore
View file @
2d543899
...
@@ -114,5 +114,6 @@ dist
...
@@ -114,5 +114,6 @@ dist
*.retry
*.retry
wgfrp-setconf.conf.j2
wgfrp-setconf.conf.j2
certs
__pycache__
__pycache__
ansible/protocols/oc/configure.yaml
0 → 100644
View file @
2d543899
-
name
:
'
{{conn.name}}:
stop
wireguard'
become
:
true
ignore_errors
:
true
systemd
:
name
:
'
wg-quick@{{conn.name}}'
state
:
stopped
enabled
:
no
-
name
:
ansible/protocols/oc/ocserv-per-user.conf.j2
0 → 100644
View file @
2d543899
explicit-ipv4 = {{conn.remoteLocalAddress}}
route = {{conn.localPeerAddress}}/32
ansible/protocols/oc/ocserv-pre.yaml
0 → 100644
View file @
2d543899
ansible/protocols/oc/ocserv.conf.j2
0 → 100644
View file @
2d543899
auth = "plain[passwd=/etc/ocserv/ocpasswd]"
listen-host-is-dyndns = true
tcp-port = {{ocservPort}}
udp-port = {{ocservPort}}
run-as-user = nobody
run-as-group = daemon
socket-file = /run/ocserv.socket
server-cert = /etc/ssl/certs/fullchain.pem
server-key = /etc/ssl/certs/privkey.pem
dh-params = /etc/ssl/certs/dhparam.pem
isolate-workers = true
server-stats-reset-time = 604800
keepalive = 300
dpd = 60
mobile-dpd = 300
switch-to-tcp-timeout = 25
try-mtu-discovery = false
cert-user-oid = 0.9.2342.19200300.100.1.1
compression = true
no-compress-limit = 256
tls-priorities = "PERFORMANCE:%SERVER_PRECEDENCE"
match-tls-dtls-ciphers = false
auth-timeout = 240
idle-timeout = 1200
mobile-idle-timeout = 1800
max-ban-score = 80
ban-reset-time = 300
cookie-timeout = 604800
deny-roaming = false
rekey-time = 172800
rekey-method = ssl
connect-script = {{ansible_user_dir}}/nextgen-network/scripts/ocserv-postup.sh
disconnect-script = {{ansible_user_dir}}/nextgen-network/scripts/ocserv-predown.sh
use-occtl = true
pid-file = /run/ocserv.pid
predictable-ips = true
ipv4-network = {{address}}/32
ping-leases = false
# route = 10.198.0.53/32
config-per-user = /etc/ocserv/config-per-user/
cisco-client-compat = false
dtls-legacy = true
ansible/protocols/oc/openconnect-postdown.sh.j2
0 → 100644
View file @
2d543899
#!/bin/bash
dev
=
"
$TUNDEV
"
localPeerAddress
={{
conn.localPeerAddress
}}
remotePeerAddress
={{
conn.remotePeerAddress
}}
link6Address
={{
conn.link6Address
}}
remoteNextMark
={{
conn.remoteNextMark
}}
inbound
={{
conn.inbound
}}
outbound
={{
conn.outbound
}}
mtu
={{
conn.mtu|int - 66
}}
{{
ansible_user_dir
}}
/nextgen-network/scripts/predown.sh
ansible/protocols/oc/openconnect-postup.sh.j2
0 → 100644
View file @
2d543899
#!/bin/bash
dev
=
"
$TUNDEV
"
localPeerAddress
={{
conn.localPeerAddress
}}
remotePeerAddress
={{
conn.remotePeerAddress
}}
link6Address
={{
conn.link6Address
}}
remoteNextMark
={{
conn.remoteNextMark
}}
inbound
={{
conn.inbound
}}
outbound
={{
conn.outbound
}}
mtu
={{
conn.mtu|int - 66
}}
{{
ansible_user_dir
}}
/nextgen-network/scripts/postup.sh
src/inventory.ts
View file @
2d543899
...
@@ -8,6 +8,16 @@ import child_process from 'child_process';
...
@@ -8,6 +8,16 @@ 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
'
;
import
{
promises
as
dns
}
from
'
dns
'
;
import
{
off
}
from
'
process
'
;
import
os
from
"
os
"
;
async
function
generateOcpasswdLine
(
username
:
string
,
password
:
string
)
{
const
tmpName
=
os
.
tmpdir
()
+
"
/
"
+
Math
.
floor
(
Math
.
random
()
*
10000000
);
await
util
.
promisify
(
child_process
.
exec
)(
`echo "
${
password
}
\\n
${
password
}
" | ocpasswd -c
${
tmpName
}
${
username
}
`
);
const
res
=
(
await
fs
.
promises
.
readFile
(
tmpName
,
"
utf-8
"
)).
trim
();
await
fs
.
promises
.
unlink
(
tmpName
);
return
res
;
}
class
InventoryBuilder
{
class
InventoryBuilder
{
hosts
:
{
[
key
:
string
]:
any
};
hosts
:
{
[
key
:
string
]:
any
};
...
@@ -16,6 +26,7 @@ class InventoryBuilder {
...
@@ -16,6 +26,7 @@ class InventoryBuilder {
routeLists
:
any
;
routeLists
:
any
;
resolveCache
:
Map
<
string
,
string
>
;
resolveCache
:
Map
<
string
,
string
>
;
resolver
:
dns
.
Resolver
;
resolver
:
dns
.
Resolver
;
vars
:
any
;
async
resolveDomain
(
domain
:
string
,
ipv6
:
boolean
)
{
async
resolveDomain
(
domain
:
string
,
ipv6
:
boolean
)
{
if
(
!
domain
||
domain
.
match
(
/
(\d{1,3}\.){3}\d{1,3}
/
))
{
if
(
!
domain
||
domain
.
match
(
/
(\d{1,3}\.){3}\d{1,3}
/
))
{
...
@@ -90,7 +101,7 @@ class InventoryBuilder {
...
@@ -90,7 +101,7 @@ class InventoryBuilder {
const
rawHosts
=
await
Promise
.
all
(
Object
.
values
(
this
.
hosts
).
map
(
async
(
h
)
=>
[
h
.
name
,
await
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
();
this
.
vars
=
await
this
.
loadUtilities
();
const
rawHostsForSwitch
=
rawHosts
.
map
(
rh
=>
{
const
rawHostsForSwitch
=
rawHosts
.
map
(
rh
=>
{
const
hostVars
=
JSON
.
parse
(
JSON
.
stringify
(
rh
[
1
]));
const
hostVars
=
JSON
.
parse
(
JSON
.
stringify
(
rh
[
1
]));
hostVars
.
ansible_ssh_host
=
hostVars
.
address
;
hostVars
.
ansible_ssh_host
=
hostVars
.
address
;
...
@@ -99,8 +110,8 @@ class InventoryBuilder {
...
@@ -99,8 +110,8 @@ class InventoryBuilder {
});
});
const
switchHosts
=
Object
.
fromEntries
(
rawHostsForSwitch
);
const
switchHosts
=
Object
.
fromEntries
(
rawHostsForSwitch
);
const
result
=
YAML
.
stringify
({
const
result
=
YAML
.
stringify
({
wg
:
{
hosts
,
vars
},
wg
:
{
hosts
,
vars
:
this
.
vars
},
switch
:
{
hosts
:
switchHosts
,
vars
:
JSON
.
parse
(
JSON
.
stringify
(
vars
))
}
switch
:
{
hosts
:
switchHosts
,
vars
:
JSON
.
parse
(
JSON
.
stringify
(
this
.
vars
))
}
});
});
return
fs
.
promises
.
writeFile
(
'
result/inventory.yaml
'
,
result
);
return
fs
.
promises
.
writeFile
(
'
result/inventory.yaml
'
,
result
);
}
}
...
@@ -155,6 +166,7 @@ class InventoryBuilder {
...
@@ -155,6 +166,7 @@ class InventoryBuilder {
const
lanInterfaces
=
host
.
lanInterfaces
;
const
lanInterfaces
=
host
.
lanInterfaces
;
const
masqInterfaces
=
host
.
masqInterfaces
.
length
>
0
?
host
.
masqInterfaces
.
split
(
'
,
'
)
:
[];
const
masqInterfaces
=
host
.
masqInterfaces
.
length
>
0
?
host
.
masqInterfaces
.
split
(
'
,
'
)
:
[];
const
routePlans
=
[];
const
routePlans
=
[];
for
(
const
h
of
this
.
connections
)
{
for
(
const
h
of
this
.
connections
)
{
if
(
h
!=
host
.
name
)
{
if
(
h
!=
host
.
name
)
{
const
to
=
host
[
h
];
// 当前主机的条目
const
to
=
host
[
h
];
// 当前主机的条目
...
@@ -191,6 +203,8 @@ class InventoryBuilder {
...
@@ -191,6 +203,8 @@ class InventoryBuilder {
key
:
host
.
wgPrivateKey
,
key
:
host
.
wgPrivateKey
,
frpsNeeded
:
host
.
frpsNeeded
,
frpsNeeded
:
host
.
frpsNeeded
,
frpsPort
:
host
.
frpsPort
,
frpsPort
:
host
.
frpsPort
,
ocservPort
:
host
.
ocservPort
,
ocservCert
:
host
.
ocservCert
||
null
,
gateways
:
_
.
values
(
this
.
gateways
[
host
.
name
]),
gateways
:
_
.
values
(
this
.
gateways
[
host
.
name
]),
connections
,
connections
,
lanInterfaces
,
lanInterfaces
,
...
@@ -198,7 +212,7 @@ class InventoryBuilder {
...
@@ -198,7 +212,7 @@ class InventoryBuilder {
dockerServices
:
host
.
dockerServices
,
dockerServices
:
host
.
dockerServices
,
routePlans
,
routePlans
,
noBird
:
!!
(
host
.
noBird
||
host
.
sysBird
),
noBird
:
!!
(
host
.
noBird
||
host
.
sysBird
),
systemBird
:
!!
host
.
sysBird
systemBird
:
!!
host
.
sysBird
,
};
};
}
}
...
@@ -231,12 +245,14 @@ class InventoryBuilder {
...
@@ -231,12 +245,14 @@ class InventoryBuilder {
const
localPort
=
(
primary
?
remote
.
port
:
remote
.
port2
)
+
local
.
offset
;
const
localPort
=
(
primary
?
remote
.
port
:
remote
.
port2
)
+
local
.
offset
;
const
remotePort
=
(
primary
?
local
.
port
:
local
.
port2
)
+
remote
.
offset
;
const
remotePort
=
(
primary
?
local
.
port
:
local
.
port2
)
+
remote
.
offset
;
const
remoteFrpsPort
=
remote
.
frpsPort
;
const
remoteFrpsPort
=
remote
.
frpsPort
;
const
remoteOcservPort
=
remote
.
ocservPort
;
const
wgPublicKey
=
remote
.
wgPublickey
;
const
wgPublicKey
=
remote
.
wgPublickey
;
const
localPeerAddress
=
primary
?
`10.200.
${
local
.
id
}
.
${
remote
.
id
}
`
:
`10.201.
${
local
.
id
}
.
${
remote
.
id
}
`
;
const
localPeerAddress
=
primary
?
`10.200.
${
local
.
id
}
.
${
remote
.
id
}
`
:
`10.201.
${
local
.
id
}
.
${
remote
.
id
}
`
;
const
remotePeerAddress
=
primary
?
`10.200.
${
remote
.
id
}
.
${
local
.
id
}
`
:
`10.201.
${
remote
.
id
}
.
${
local
.
id
}
`
;
const
remotePeerAddress
=
primary
?
`10.200.
${
remote
.
id
}
.
${
local
.
id
}
`
:
`10.201.
${
remote
.
id
}
.
${
local
.
id
}
`
;
const
link6Address
=
`fe80::
${
primary
?
1
:
2
}
:
${
local
.
id
}
:
${
remote
.
id
}
/64`
;
const
link6Address
=
`fe80::
${
primary
?
1
:
2
}
:
${
local
.
id
}
:
${
remote
.
id
}
/64`
;
const
frpType
=
protocol
===
'
wgfrp
'
?
(
this
.
gatewayCompare
(
localGateway
,
remoteGateway
)
?
'
frps
'
:
'
frpc
'
)
:
undefined
;
const
frpType
=
protocol
===
'
wgfrp
'
?
(
this
.
gatewayCompare
(
localGateway
,
remoteGateway
)
?
'
frps
'
:
'
frpc
'
)
:
undefined
;
const
ocType
=
protocol
===
'
oc
'
?
(
this
.
gatewayCompareOcserv
(
local
,
remote
,
localGateway
,
remoteGateway
)
?
'
server
'
:
'
client
'
)
:
undefined
;
if
(
frpType
===
'
frps
'
&&
!
local
.
dockerServices
.
services
.
frps
)
{
if
(
frpType
===
'
frps
'
&&
!
local
.
dockerServices
.
services
.
frps
)
{
local
.
frpsNeeded
=
true
;
local
.
frpsNeeded
=
true
;
...
@@ -259,6 +275,45 @@ class InventoryBuilder {
...
@@ -259,6 +275,45 @@ class InventoryBuilder {
};
};
}
}
if
(
ocType
===
'
server
'
)
{
if
(
!
local
.
dockerServices
.
services
.
ocserv
)
{
local
.
ocservNeeded
=
true
;
local
.
ocpasswdLines
=
[];
local
.
dockerServices
.
services
.
ocserv
=
{
restart
:
'
always
'
,
image
:
'
git-registry.mycard.moe/nanahira/docker-ocserv
'
,
network_mode
:
'
host
'
,
command
:
'
ocserv -f -d 1
'
,
cap_add
:
[
'
NET_ADMIN
'
],
devices
:
[
'
/dev/net/tun:/dev/net/tun
'
],
volumes
:
[
'
./ocserv/ocserv.conf:/etc/ocserv.conf:ro
'
,
'
./ocserv/config-per-user:/etc/ocserv/config-per-user:ro
'
,
'
./ocserv/env-per-user:/etc/ocserv/env-per-user:ro
'
,
'
./ocserv/ocpasswd:/etc/ocserv/ocpasswd:ro
'
,
'
./ocserv/certs:/etc/ssl/certs:ro
'
,
'
$HOME/nextgen-network/scripts:$HOME/nextgen-network/scripts:ro
'
]
};
}
local
.
ocpasswdLines
.
push
(
await
generateOcpasswdLine
(
name
,
this
.
vars
.
ocservPassword
));
}
if
(
ocType
===
'
client
'
)
{
local
.
dockerServices
.
services
[
`openconnect-
${
name
}
`
]
=
{
restart
:
'
always
'
,
image
:
'
git-registry.mycard.moe/railgun/openconnect
'
,
network_mode
:
'
host
'
,
command
:
[
'
bash
'
,
'
-c
'
,
`echo '
${
this
.
vars
.
ocservPassword
}
' | openconnect --user=
${
name
}
--passwd-on-stdin --passtos --interface=
${
name
}
${
remoteOcservPort
}
`
],
cap_add
:
[
'
NET_ADMIN
'
],
devices
:
[
'
/dev/net/tun:/dev/net/tun
'
],
volumes
:
[
`./client-scripts/
${
name
}
:/etc/vpnc:ro`
,
'
$HOME/nextgen-network/scripts:$HOME/nextgen-network/scripts:ro
'
]
};
}
const
mtu
=
Math
.
min
(
localGateway
?
localGateway
.
mtu
:
1500
,
remoteGateway
?
remoteGateway
.
mtu
:
1500
);
const
mtu
=
Math
.
min
(
localGateway
?
localGateway
.
mtu
:
1500
,
remoteGateway
?
remoteGateway
.
mtu
:
1500
);
//console.log(local.name, name, mtu);
//console.log(local.name, name, mtu);
...
@@ -284,7 +339,9 @@ class InventoryBuilder {
...
@@ -284,7 +339,9 @@ class InventoryBuilder {
remotePeerAddress
,
remotePeerAddress
,
link6Address
,
link6Address
,
remoteFrpsPort
,
remoteFrpsPort
,
//remoteOcservPort,
frpType
,
frpType
,
ocType
,
inbound
,
inbound
,
outbound
,
outbound
,
mtu
mtu
...
@@ -293,23 +350,30 @@ class InventoryBuilder {
...
@@ -293,23 +350,30 @@ class InventoryBuilder {
// frps还是frpc的积分,NAT越有利分越高
// frps还是frpc的积分,NAT越有利分越高
gatewayCompareScore
(
gateway
:
any
):
number
{
gatewayCompareScore
(
gateway
:
any
):
number
{
let
score
:
number
=
0xff
-
gateway
.
id
;
// 8 bits
let
offset
=
0
;
let
score
=
0
score
|=
(
0xff
-
gateway
.
id
)
<<
offset
;
// 8 bits
offset
+=
8
;
const
isCNScore
=
gateway
.
isCN
?
0
:
1
;
// 1 bit
const
isCNScore
=
gateway
.
isCN
?
0
:
1
;
// 1 bit
score
|=
isCNScore
<<
8
;
score
|=
isCNScore
<<
offset
;
offset
+=
1
;
const
ipv4NatScore
=
({
// 2 bits
const
ipv4NatScore
=
({
// 2 bits
'
ports
'
:
0
,
'
ports
'
:
0
,
'
dmz
'
:
1
'
dmz
'
:
1
})[
gateway
.
ipv4Nat
]
||
2
;
})[
gateway
.
ipv4Nat
]
||
2
;
score
|=
ipv4NatScore
<<
9
;
score
|=
ipv4NatScore
<<
offset
;
offset
+=
2
;
const
ipv4Score
=
({
// 2 bits
const
ipv4Score
=
({
// 2 bits
'
static
'
:
2
,
'
static
'
:
2
,
'
dynamic
'
:
1
'
dynamic
'
:
1
})[
gateway
.
ipv4
]
||
0
;
})[
gateway
.
ipv4
]
||
0
;
score
|=
ipv4Score
<<
11
;
score
|=
ipv4Score
<<
offset
;
offset
+=
2
;
const
globalSSHScore
=
({
// 1 bit
const
globalSSHScore
=
({
// 1 bit
'
globalssh
'
:
1
'
globalssh
'
:
1
})[
gateway
.
ssh
]
||
0
;
})[
gateway
.
ssh
]
||
0
;
score
|=
globalSSHScore
<<
12
;
score
|=
globalSSHScore
<<
offset
;
offset
+=
1
;
return
score
;
return
score
;
}
}
...
@@ -328,6 +392,17 @@ class InventoryBuilder {
...
@@ -328,6 +392,17 @@ class InventoryBuilder {
return
this
.
gatewayCompareScore
(
localGateway
)
>
this
.
gatewayCompareScore
(
remoteGateway
);
return
this
.
gatewayCompareScore
(
localGateway
)
>
this
.
gatewayCompareScore
(
remoteGateway
);
}
}
gatewayCompareOcserv
(
local
:
any
,
remote
:
any
,
localGateway
:
any
,
remoteGateway
:
any
):
boolean
{
// 两边至少一个有证书才能连
assert
(
local
.
ocservCert
||
remote
.
ocservCert
);
// 只有一边有证书用有证书的那边
if
(
!!
local
.
ocservCert
!==
!!
remote
.
ocservCert
)
{
return
!!
local
.
ocservCert
;
}
return
this
.
gatewayCompare
(
localGateway
,
remoteGateway
);
}
async
wgPublickey
(
privateKey
)
{
async
wgPublickey
(
privateKey
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
child
=
child_process
.
execFile
(
'
wg
'
,
[
'
pubkey
'
],
{
encoding
:
'
utf8
'
},
(
error
,
stdout
,
stderr
)
=>
{
const
child
=
child_process
.
execFile
(
'
wg
'
,
[
'
pubkey
'
],
{
encoding
:
'
utf8
'
},
(
error
,
stdout
,
stderr
)
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment