Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
R
re6stnet
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
2
Issues
2
List
Boards
Labels
Milestones
Merge Requests
4
Merge Requests
4
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
re6stnet
Commits
212242ff
Commit
212242ff
authored
Sep 06, 2012
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Documentation
parent
1c70c3ed
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
285 additions
and
466 deletions
+285
-466
README
README
+23
-34
docs/re6st-conf.rst
docs/re6st-conf.rst
+6
-52
docs/re6st-registry.rst
docs/re6st-registry.rst
+11
-38
docs/re6stnet.rst
docs/re6stnet.rst
+42
-237
re6st-conf
re6st-conf
+64
-41
re6st-registry
re6st-registry
+48
-30
re6st/utils.py
re6st/utils.py
+38
-1
re6stnet
re6stnet
+52
-33
setup.py
setup.py
+1
-0
No files found.
README
View file @
212242ff
...
@@ -15,32 +15,28 @@ re6stnet creates a resilient, scalable, ipv6 network on top of an existing ipv4
...
@@ -15,32 +15,28 @@ re6stnet creates a resilient, scalable, ipv6 network on top of an existing ipv4
network, by creating tunnels on the fly, and then routing targeted traffic
network, by creating tunnels on the fly, and then routing targeted traffic
through these tunnels.
through these tunnels.
re6stnet can be used to
:
re6stnet can be used to:
- guarantee connectedness between computers connected to the
- guarantee connectedness between computers connected to the
internet, for which there exists a working route (
in case the direct route
internet, for which there exists a working route (in case the direct route
isn't available
).
isn't available).
- create
very
large networks
- create large networks
- give ipv6 addresses to machines with only ipv4 available
- give ipv6 addresses to machines with only ipv4 available
HOW IT WORKS
HOW IT WORKS
============
============
A re6stnet networks consists of at least one server ( re6st-registry ) and many
A re6stnet network consists of at least one server (re6st-registry) and many
clients or nodes ( re6stnet ). The server delivers certificates for secure
nodes (re6stnet). The server is only used to deliver certificates for secure
authentification in establishing tunnels, and - for now - store the complete
authentification in establishing tunnels, and to bootstrap new nodes.
list of nodes running.
re6stnet can detect and take into account nodes present on the local network.
re6stnet detects and take into accounts nodes present on the local network.
Resilience
Resilience
----------
----------
re6stnet
can guarantee
that if there exists a route between two machines,
re6stnet
guarantees
that if there exists a route between two machines,
traffic will be correctly routed between these two machines.
traffic will be correctly routed between these two machines.
Since the destination of established connection are random, there can be no
Even if the registry node is down, the probability that the network isn't
guarantee that such a route exists given which tunnels are established, but
connected is very low for big enough networks (more than a hundred nodes).
for big enough networks ( more than a hundred nodes ), the probability that
the network isn't connected is very low.
Scalability
Scalability
-----------
-----------
...
@@ -51,30 +47,23 @@ scalable to tens of thousand of nodes
...
@@ -51,30 +47,23 @@ scalable to tens of thousand of nodes
Requirements
Requirements
============
============
- Python 2.7 or later
- Python 2.6 or 2.7
- OpenSSL binary and development libraries
- OpenSSL binary and development libraries
- OpenVPN
- OpenVPN
- Babel_
- python-miniupnpc for UPnP support (optional)
- for the demo: miniupnpd_, Graphviz, Screen, Nemu_
- Babel ( http://www.pps.univ-paris-diderot.fr/~jch/software/babel/ )
See also `setup.py` for Python dependencies.
.. _Babel: http://www.pps.univ-paris-diderot.fr/~jch/software/babel/
_Nemu: http://code.google.com/p/nemu/
_miniupnpd: http://miniupnp.free.fr/
Installation
Installation
============
============
Let's explain how to install the egg
re6stnet is distributed as an Python egg, and is also packaged for Debian.
Commercial Support
==================
Later....
.. The organisation of the code
See `re6stnet-registry` to set up a re6st network
re6stnet.py Client : Init and main loop
and `re6stnet-conf` to join an existing network.
re6st/plib.py Launch server/client/routing processes
re6st/utils.py Small functions to do useful jobs
re6st/db.py Manage the peer database
re6st/tunnel.py Manage the tunnels
re6st/upnpigd.py Forward ports
re6st-conf.py Get certificates from server
re6st-registry.py Server : deliver certificates and distribute peers
docs/re6st-conf.rst
View file @
212242ff
...
@@ -12,67 +12,21 @@ Configuration tool for re6stnet
...
@@ -12,67 +12,21 @@ Configuration tool for re6stnet
SYNOPSIS
SYNOPSIS
========
========
``re6st-conf`` ``--server`` `server-url` ``--port`` `server-port` [`command`]
``re6st-conf`` ``--registry`` `url` [`options`...]
[`options`...]
DESCRIPTION
DESCRIPTION
===========
===========
re6st-conf is a tool generating the files necessary
for re6stnet to run. I
t
re6st-conf is a tool generating the files necessary
to add a node to a re6s
t
connects to a distant server to generate the certificates files used by openvpn
network. It connects to the re6st registry to get a signed certificate with
in re6st
net.
an allocated IPv6 sub
net.
USAGE
USAGE
=====
=====
re6st-conf needs address of node running re6st-registry.
Use ``re6st-conf --help`` to get the complete list of options.
--registry address
Public HTTP URL of the registry, which is used for bootstrapping
and delivering certificates.
Commands
--------
You may give at most one of the following commands. Giving the two commands
will not raise any errors, but does not have any meaning.
--email email-address
The email address to associate with your certificates. Refrain
re6st-conf from asking you your email address in a prompt. Useful
for automatizing the configuration process.
re6st-conf will ask you the token you received by email.
--token token
Give your token if you have already received one but did not
complete the configuration process. re6st-conf will not ask you
anything. If you use this option, you do not need to give your
email address.
Options
-------
-d, ``--dir`` `directory`
Path of a directory where will be stored the files generated by the
setup. The Setup genereates the following files, in the explicit
order :
- ca.pem : certificate authority file downloaded from the server
- cert.key : private key generated by the script
- cert.crt : individual certificate file generated by the server
- dh2048.pem : dh file for oenvpn server
-r, ``--req`` `name` `value`
Specify an attribute to add to the certificate request sent to the
server. Can be used multiple times.
Each use of the --req name value, will add the attribute name with
the associated value in the sugbject of the certificate request.
--ca-only
Stop the script after downloading the certificate authority file
from the server
SEE ALSO
SEE ALSO
========
========
``re6stnet``\ (
1), ``re6st-registry``\ (1
)
``re6stnet``\ (
8
)
docs/re6st-registry.rst
View file @
212242ff
...
@@ -12,55 +12,28 @@
...
@@ -12,55 +12,28 @@
SYNOPSIS
SYNOPSIS
========
========
``re6st-registry`` `port` ``--db`` `db-path` ``--ca`` `ca-path`
``re6st-registry`` ``--db`` `db-path` ``--ca`` `ca-path` ``--key`` `key-path`
``--key`` `key-path` ``--mailhost`` `mailhost` ``--private`` `private-ip`
``--mailhost`` `mailhost` ``--private`` `re6st-ip` [`options`...]
[`options`...]
DESCRIPTION
DESCRIPTION
===========
===========
re6st-registry is a server for the re6st network. Its role is to deliver
re6st-registry is a server for the re6st network. Its role is to deliver
certificates to new nodes, and to
maintain the complete table of peers, so it
certificates to new nodes, and to
bootstrap nodes that don't know any address
can send part of it to nodes asking for new peer
s.
of other node
s.
Only one re6st-registry per re6st network should run. The node
running the re6st-registry must also have a client ( re6stnet ) running
.
The network can host only one registry, which should run on a re6st node
.
USAGE
USAGE
=====
=====
The re6st-registry will automatically listen on both ipv4 and ipv6 for incoming
Use ``re6st-registry --help`` to get the complete list of options.
request.
--port port
The port on which the server will listen
Default: 80
--db path
Path to the server Database file. A new DB file will be created
and correctly initialized if the file doesn't exists.
One can give ":memory" as path, the database is then temporary
--ca path
Path to the certificate authority file. The certificate authority
MUST contain the VPN network prefix in its serial number. To
generate correct ca and key files for the 2001:db8:42:: prefix,
the following command can be used :
openssl req -nodes -new -x509 -key ca.key -set_serial \
0x120010db80042 -days 365 -out ca.crt
--key path
Path to the server key file. To generate a key file, see the --ca
option
--mailhost mailhost
Mailhost to be used to send email containing token for registration
--private ip
The network prefix can be changed by renewing the Certificate authority with
Ipv6 address of the re6stnet client running on the machine. This
a different serial number, but keeping the existing key. Then all nodes of the
address will be advertised only to nodes having a valid
network must fetch the new CA with `re6st-conf` and restart `re6stnet`.
certificate.
SEE ALSO
SEE ALSO
========
========
``re6stnet``\ (
1), ``re6st-conf``\ (1
)
``re6stnet``\ (
8
)
docs/re6stnet.rst
View file @
212242ff
This diff is collapsed.
Click to expand it.
re6st-conf
View file @
212242ff
#!/usr/bin/env python
#!/usr/bin/env python
import
argparse
,
os
,
subprocess
,
sqlite3
,
sys
,
xmlrpclib
import
argparse
,
atexit
,
os
,
subprocess
,
sqlite3
,
sys
,
xmlrpclib
from
OpenSSL
import
crypto
from
OpenSSL
import
crypto
from
re6st
import
utils
from
re6st
import
utils
def
create
(
path
,
text
,
mode
=
0666
):
def
create
(
path
,
text
=
None
,
mode
=
0666
):
fd
=
os
.
open
(
path
,
os
.
O_CREAT
|
os
.
O_WRONLY
|
os
.
O_EXCL
,
mode
)
fd
=
os
.
open
(
path
,
os
.
O_CREAT
|
os
.
O_WRONLY
|
os
.
O_TRUNC
,
mode
)
if
text
is
None
:
return
fd
try
:
try
:
os
.
write
(
fd
,
text
)
os
.
write
(
fd
,
text
)
finally
:
finally
:
...
@@ -12,18 +14,24 @@ def create(path, text, mode=0666):
...
@@ -12,18 +14,24 @@ def create(path, text, mode=0666):
def
main
():
def
main
():
parser
=
argparse
.
ArgumentParser
(
parser
=
argparse
.
ArgumentParser
(
description
=
'Setup script for re6stnet'
)
description
=
"Setup script for re6stnet."
,
formatter_class
=
utils
.
HelpFormatter
)
_
=
parser
.
add_argument
_
=
parser
.
add_argument
_
(
'--registry'
,
required
=
True
,
metavar
=
'URL'
,
help
=
"HTTP URL of the server delivering certificates."
)
_
(
'--ca-only'
,
action
=
'store_true'
,
_
(
'--ca-only'
,
action
=
'store_true'
,
help
=
'To only get CA form server'
)
help
=
'Only fetch CA from registry and exit.'
)
_
(
'--registry'
,
required
=
True
,
_
(
'-d'
,
'--dir'
,
help
=
'HTTP URL of the server delivering certificates'
)
help
=
"Directory where the key and certificate will be stored."
)
_
(
'-d'
,
'--dir'
,
default
=
'/etc/re6stnet'
,
_
(
'-r'
,
'--req'
,
nargs
=
2
,
action
=
'append'
,
metavar
=
(
'KEY'
,
'VALUE'
),
help
=
'Directory where the key and certificate will be stored'
)
help
=
"The registry only sets the Common Name of your certificate,"
_
(
'-r'
,
'--req'
,
nargs
=
2
,
action
=
'append'
,
" which actually encodes your allocated prefix in the network."
help
=
'Name and value of certificate request additional arguments'
)
" You can repeat this option to add any field you want to its"
_
(
'--email'
,
help
=
'Your email address'
)
" subject."
)
_
(
'--token'
,
help
=
'The token you received'
)
_
(
'--email'
,
help
=
"Email address where your token is sent. Use -r option if you"
" want to show an email in your certificate."
)
_
(
'--token'
,
help
=
"The token you received."
)
config
=
parser
.
parse_args
()
config
=
parser
.
parse_args
()
if
config
.
dir
:
if
config
.
dir
:
os
.
chdir
(
config
.
dir
)
os
.
chdir
(
config
.
dir
)
...
@@ -36,45 +44,60 @@ def main():
...
@@ -36,45 +44,60 @@ def main():
s
=
xmlrpclib
.
ServerProxy
(
config
.
registry
)
s
=
xmlrpclib
.
ServerProxy
(
config
.
registry
)
# Get CA
# Get CA
ca
=
s
.
getCa
()
create
(
ca_path
,
s
.
getCa
())
create
(
ca_path
,
ca
)
if
config
.
ca_only
:
if
config
.
ca_only
:
sys
.
exit
()
sys
.
exit
()
# Get token
# Generating dh file
if
not
config
.
token
:
if
not
os
.
access
(
dh_path
,
os
.
F_OK
):
if
not
config
.
email
:
r
=
subprocess
.
call
((
'openssl'
,
'dhparam'
,
'-out'
,
dh_path
,
'2048'
))
config
.
email
=
raw_input
(
'Please enter your email address : '
)
if
r
:
_
=
s
.
requestToken
(
config
.
email
)
sys
.
exit
(
r
)
config
.
token
=
raw_input
(
'Please enter your token : '
)
# Generate key and cert request
pkey
=
crypto
.
PKey
()
pkey
.
generate_key
(
crypto
.
TYPE_RSA
,
2048
)
key
=
crypto
.
dump_privatekey
(
crypto
.
FILETYPE_PEM
,
pkey
)
req
=
crypto
.
X509Req
()
req
=
crypto
.
X509Req
()
subj
=
req
.
get_subject
()
subj
=
req
.
get_subject
()
if
config
.
req
:
if
config
.
req
:
for
arg
in
config
.
req
:
for
k
,
v
in
config
.
req
:
setattr
(
subj
,
arg
[
0
],
arg
[
1
])
if
k
==
'CN'
:
req
.
set_pubkey
(
pkey
)
sys
.
exit
(
"CN field is reserved."
)
req
.
sign
(
pkey
,
'sha1'
)
setattr
(
subj
,
k
,
v
)
req
=
crypto
.
dump_certificate_request
(
crypto
.
FILETYPE_PEM
,
req
)
# Get certificate
cert_fd
=
token_advice
=
None
cert
=
s
.
requestCertificate
(
config
.
token
,
req
)
try
:
if
not
config
.
token
:
if
not
config
.
email
:
config
.
email
=
raw_input
(
'Please enter your email address: '
)
s
.
requestToken
(
config
.
email
)
token_advice
=
"Use --token to retry without asking a new token
\
n
"
config
.
token
=
raw_input
(
'Please enter your token: '
)
# Store cert and key
# First make sure we can store private key and open certificate file
create
(
key_path
,
key
,
0600
)
# for writing, to avoid using our token for nothing.
create
(
cert_path
,
cert
)
print
"Generating key and cert requests ..."
cert_fd
=
create
(
cert_path
)
pkey
=
crypto
.
PKey
()
pkey
.
generate_key
(
crypto
.
TYPE_RSA
,
2048
)
key
=
crypto
.
dump_privatekey
(
crypto
.
FILETYPE_PEM
,
pkey
)
# Generating dh file
req
.
set_pubkey
(
pkey
)
if
not
os
.
access
(
dh_path
,
os
.
F_OK
):
req
.
sign
(
pkey
,
'sha1'
)
r
=
subprocess
.
call
((
'openssl'
,
'dhparam'
,
'-out'
,
dh_path
,
'2048'
))
req
=
crypto
.
dump_certificate_request
(
crypto
.
FILETYPE_PEM
,
req
)
if
r
:
sys
.
exit
(
r
)
create
(
key_path
,
key
,
0600
)
print
"Requesting certificate ..."
cert
=
s
.
requestCertificate
(
config
.
token
,
req
)
if
not
cert
:
token_advice
=
None
sys
.
exit
(
"Error: invalid or expired token"
)
except
:
if
cert_fd
:
os
.
remove
(
cert_path
)
if
token_advice
:
atexit
.
register
(
sys
.
stdout
.
write
,
token_advice
)
raise
os
.
write
(
cert_fd
,
cert
)
os
.
close
(
cert_fd
)
print
"Certificate setup complete."
print
"Certificate setup complete."
...
...
re6st-registry
View file @
212242ff
...
@@ -50,26 +50,35 @@ class main(object):
...
@@ -50,26 +50,35 @@ class main(object):
# Command line parsing
# Command line parsing
parser
=
utils
.
ArgParser
(
fromfile_prefix_chars
=
'@'
,
parser
=
utils
.
ArgParser
(
fromfile_prefix_chars
=
'@'
,
description
=
'Peer discovery http server for re6stnet'
)
description
=
"re6stnet registry used to bootstrap nodes"
" and deliver certificates."
)
_
=
parser
.
add_argument
_
=
parser
.
add_argument
_
(
'--port'
,
type
=
int
,
default
=
80
,
help
=
'Port of the host server'
)
_
(
'--port'
,
type
=
int
,
default
=
80
,
_
(
'--db'
,
required
=
True
,
help
=
"Port on which the server will listen."
)
help
=
'Path to database file'
)
_
(
'-4'
,
dest
=
'bind4'
,
default
=
'0.0.0.0'
,
_
(
'--ca'
,
required
=
True
,
help
=
"Bind server to this IPv4."
)
help
=
'Path to ca.crt file'
)
_
(
'-6'
,
dest
=
'bind6'
,
default
=
'::'
,
help
=
"Bind server to this IPv6."
)
_
(
'--db'
,
default
=
'/var/lib/re6stnet/registry.db'
,
help
=
"Path to SQLite database file. It is automatically initialized"
" if the file does not exist."
)
_
(
'--ca'
,
required
=
True
,
help
=
parser
.
_ca_help
)
_
(
'--key'
,
required
=
True
,
_
(
'--key'
,
required
=
True
,
help
=
'Path to certificate key'
)
help
=
"CA private key in .pem format."
)
_
(
'--mailhost'
,
required
=
True
,
_
(
'--mailhost'
,
required
=
True
,
help
=
'SMTP server mail host; for debugging purpose, it can also'
help
=
"SMTP host to send confirmation emails. For debugging"
' be an absolute or existing path to a mailbox file'
)
" purpose, it can also be an absolute or existing path to"
" a mailbox file"
)
_
(
'--private'
,
_
(
'--private'
,
help
=
'VPN IP of the node on which runs the registry'
)
help
=
"re6stnet IP of the node on which runs the registry."
" Required for normal operation."
)
_
(
'--prefix-length'
,
default
=
16
,
_
(
'--prefix-length'
,
default
=
16
,
help
=
'Default length of allocated prefixes'
)
help
=
"Default length of allocated prefixes."
)
_
(
'-l'
,
'--logfile'
,
default
=
'/var/log/re6stnet/registry.log'
,
_
(
'-l'
,
'--logfile'
,
default
=
'/var/log/re6stnet/registry.log'
,
help
=
'Path to logging file'
)
help
=
"Path to logging file."
)
_
(
'-v'
,
'--verbose'
,
default
=
1
,
type
=
int
,
_
(
'-v'
,
'--verbose'
,
default
=
1
,
type
=
int
,
help
=
'Log level'
)
help
=
"Log level. 0 disables logging."
" Use SIGUSR1 to reopen log."
)
self
.
config
=
parser
.
parse_args
()
self
.
config
=
parser
.
parse_args
()
utils
.
setupLog
(
self
.
config
.
verbose
,
self
.
config
.
logfile
)
utils
.
setupLog
(
self
.
config
.
verbose
,
self
.
config
.
logfile
)
...
@@ -82,6 +91,7 @@ class main(object):
...
@@ -82,6 +91,7 @@ class main(object):
'check you configuration'
)
'check you configuration'
)
# Database initializing
# Database initializing
utils
.
makedirs
(
os
.
path
.
dirname
(
self
.
config
.
db
))
self
.
db
=
sqlite3
.
connect
(
self
.
config
.
db
,
isolation_level
=
None
)
self
.
db
=
sqlite3
.
connect
(
self
.
config
.
db
,
isolation_level
=
None
)
self
.
db
.
execute
(
"""CREATE TABLE IF NOT EXISTS token (
self
.
db
.
execute
(
"""CREATE TABLE IF NOT EXISTS token (
token text primary key not null,
token text primary key not null,
...
@@ -111,21 +121,30 @@ class main(object):
...
@@ -111,21 +121,30 @@ class main(object):
self
.
_email
=
self
.
ca
.
get_subject
().
emailAddress
self
.
_email
=
self
.
ca
.
get_subject
().
emailAddress
# Starting server
# Starting server
server4
=
SimpleXMLRPCServer4
((
'0.0.0.0'
,
self
.
config
.
port
),
requestHandler
=
RequestHandler
,
allow_none
=
True
)
server_list
=
[]
server4
.
register_instance
(
self
)
if
self
.
config
.
bind4
:
server6
=
SimpleXMLRPCServer6
((
'::'
,
self
.
config
.
port
),
requestHandler
=
RequestHandler
,
allow_none
=
True
)
server4
=
SimpleXMLRPCServer4
((
self
.
config
.
bind4
,
self
.
config
.
port
),
server6
.
register_instance
(
self
)
requestHandler
=
RequestHandler
,
allow_none
=
True
)
server4
.
register_instance
(
self
)
# Main loop
server_list
.
append
(
server4
)
while
True
:
if
self
.
config
.
bind6
:
try
:
server6
=
SimpleXMLRPCServer6
((
self
.
config
.
bind6
,
self
.
config
.
port
),
r
=
select
.
select
([
server4
,
server6
],
[],
[])[
0
]
requestHandler
=
RequestHandler
,
allow_none
=
True
)
except
select
.
error
as
e
:
server6
.
register_instance
(
self
)
if
e
.
args
[
0
]
!=
errno
.
EINTR
:
server_list
.
append
(
server6
)
raise
else
:
if
len
(
server_list
)
==
1
:
for
r
in
r
:
server_list
[
0
].
serve_forever
()
r
.
_handle_request_noblock
()
else
:
while
True
:
try
:
r
=
select
.
select
(
server_list
[:],
[],
[])[
0
]
except
select
.
error
as
e
:
if
e
.
args
[
0
]
!=
errno
.
EINTR
:
raise
else
:
for
r
in
r
:
r
.
_handle_request_noblock
()
def
requestToken
(
self
,
handler
,
email
):
def
requestToken
(
self
,
handler
,
email
):
while
True
:
while
True
:
...
@@ -183,8 +202,7 @@ class main(object):
...
@@ -183,8 +202,7 @@ class main(object):
try
:
try
:
token
,
email
,
prefix_len
,
_
=
self
.
db
.
execute
(
"SELECT * FROM token WHERE token = ?"
,
(
token
,)).
next
()
token
,
email
,
prefix_len
,
_
=
self
.
db
.
execute
(
"SELECT * FROM token WHERE token = ?"
,
(
token
,)).
next
()
except
StopIteration
:
except
StopIteration
:
logging
.
exception
(
'Bad token (%s) in request'
,
token
)
return
raise
self
.
db
.
execute
(
"DELETE FROM token WHERE token = ?"
,
(
token
,))
self
.
db
.
execute
(
"DELETE FROM token WHERE token = ?"
,
(
token
,))
# Get a new prefix
# Get a new prefix
...
...
re6st/utils.py
View file @
212242ff
import
argparse
,
errno
,
logging
,
os
,
signal
,
struct
,
socket
,
time
import
argparse
,
errno
,
logging
,
os
,
signal
,
struct
,
socket
,
t
extwrap
,
t
ime
from
OpenSSL
import
crypto
from
OpenSSL
import
crypto
logging_levels
=
logging
.
WARNING
,
logging
.
INFO
,
logging
.
DEBUG
,
5
logging_levels
=
logging
.
WARNING
,
logging
.
INFO
,
logging
.
DEBUG
,
5
...
@@ -44,8 +44,38 @@ def setupLog(log_level, filename=None, **kw):
...
@@ -44,8 +44,38 @@ def setupLog(log_level, filename=None, **kw):
logging
.
addLevelName
(
5
,
'TRACE'
)
logging
.
addLevelName
(
5
,
'TRACE'
)
logging
.
trace
=
lambda
*
args
,
**
kw
:
logging
.
log
(
5
,
*
args
,
**
kw
)
logging
.
trace
=
lambda
*
args
,
**
kw
:
logging
.
log
(
5
,
*
args
,
**
kw
)
class
HelpFormatter
(
argparse
.
ArgumentDefaultsHelpFormatter
):
def
_get_help_string
(
self
,
action
):
return
super
(
HelpFormatter
,
self
).
_get_help_string
(
action
)
\
if
action
.
default
else
action
.
help
def
_split_lines
(
self
,
text
,
width
):
"""Preserves new lines in option descriptions"""
lines
=
[]
for
text
in
text
.
splitlines
():
lines
+=
textwrap
.
wrap
(
text
,
width
)
return
lines
def
_fill_text
(
self
,
text
,
width
,
indent
):
"""Preserves new lines in other descriptions"""
kw
=
dict
(
width
=
width
,
initial_indent
=
indent
,
subsequent_indent
=
indent
)
return
'
\
n
'
.
join
(
textwrap
.
fill
(
t
,
**
kw
)
for
t
in
text
.
splitlines
())
class
ArgParser
(
argparse
.
ArgumentParser
):
class
ArgParser
(
argparse
.
ArgumentParser
):
class
_HelpFormatter
(
HelpFormatter
):
def
_format_actions_usage
(
self
,
actions
,
groups
):
r
=
HelpFormatter
.
_format_actions_usage
(
self
,
actions
,
groups
)
if
actions
and
actions
[
0
].
option_strings
:
r
=
'[@OPTIONS_FILE] '
+
r
return
r
_ca_help
=
"Certificate authority (CA) file in .pem format."
\
" Serial number defines the prefix of the network."
def
convert_arg_line_to_args
(
self
,
arg_line
):
def
convert_arg_line_to_args
(
self
,
arg_line
):
arg_line
=
arg_line
.
split
(
'#'
)[
0
].
rstrip
()
arg_line
=
arg_line
.
split
(
'#'
)[
0
].
rstrip
()
if
arg_line
:
if
arg_line
:
...
@@ -56,6 +86,13 @@ class ArgParser(argparse.ArgumentParser):
...
@@ -56,6 +86,13 @@ class ArgParser(argparse.ArgumentParser):
if
arg
.
strip
():
if
arg
.
strip
():
yield
arg
yield
arg
def
__init__
(
self
,
**
kw
):
super
(
ArgParser
,
self
).
__init__
(
formatter_class
=
self
.
_HelpFormatter
,
epilog
=
"""Options can be read from a file. For example:
$ cat OPTIONS_FILE
ca /etc/re6stnet/ca.crt"""
,
**
kw
)
def
makedirs
(
path
):
def
makedirs
(
path
):
try
:
try
:
os
.
makedirs
(
path
)
os
.
makedirs
(
path
)
...
...
re6stnet
View file @
212242ff
...
@@ -18,56 +18,75 @@ def ovpnArgs(optional_args, ca_path, cert_path, key_path):
...
@@ -18,56 +18,75 @@ def ovpnArgs(optional_args, ca_path, cert_path, key_path):
def
getConfig
():
def
getConfig
():
parser
=
utils
.
ArgParser
(
fromfile_prefix_chars
=
'@'
,
parser
=
utils
.
ArgParser
(
fromfile_prefix_chars
=
'@'
,
description
=
'Resilient virtual private network application'
)
description
=
"Resilient virtual private network application."
)
_
=
parser
.
add_argument
_
=
parser
.
add_argument
# General Configuration options
_
(
'--ip'
,
_
(
'--ip'
,
help
=
'IP address advertised to other nodes'
)
help
=
"IP address advertised to other nodes. Special values:
\
n
"
_
(
'--registry'
,
required
=
True
,
"- upnp: force autoconfiguration via UPnP
\
n
"
help
=
"HTTP URL of the discovery peer server,"
"- any: ask peers our IP
\
n
"
" with public host (default port: 80)"
)
" (default: ask peers if UPnP fails)"
)
_
(
'--registry'
,
required
=
True
,
metavar
=
'URL'
,
help
=
"Public HTTP URL of the registry, for bootstrapping."
)
_
(
'-l'
,
'--log'
,
default
=
'/var/log/re6stnet'
,
_
(
'-l'
,
'--log'
,
default
=
'/var/log/re6stnet'
,
help
=
'Path to re6stnet logs directory'
)
help
=
"Path to the directory used for log files:
\
n
"
"- re6stnet.log: log file of re6stnet itself
\
n
"
"- babeld.log: log file of router
\
n
"
"- <iface>.log: 1 file per spawned OpenVPN
\
n
"
)
_
(
'-s'
,
'--state'
,
default
=
'/var/lib/re6stnet'
,
_
(
'-s'
,
'--state'
,
default
=
'/var/lib/re6stnet'
,
help
=
'Path to re6stnet state directory'
)
help
=
"Path to re6stnet state directory:
\
n
"
_
(
'-v'
,
'--verbose'
,
default
=
1
,
type
=
int
,
"- peers.db: cache of peer addresses
\
n
"
help
=
'Log level of re6stnet itself'
)
"- babeld.state: see option -S of babeld
\
n
"
)
_
(
'-v'
,
'--verbose'
,
default
=
1
,
type
=
int
,
metavar
=
'LEVEL'
,
help
=
"Log level of re6stnet itself. 0 disables logging."
" Use SIGUSR1 to reopen log."
" See also --babel-verb and --verb for logs of spawned processes."
)
_
(
'-i'
,
'--interface'
,
action
=
'append'
,
dest
=
'iface_list'
,
default
=
[],
_
(
'-i'
,
'--interface'
,
action
=
'append'
,
dest
=
'iface_list'
,
default
=
[],
help
=
'Extra interface for LAN discovery'
)
help
=
"Extra interface for LAN discovery. Highly recommanded if there"
" are other re6st node on the same network segment."
)
# Routing algorithm options
_
(
'--babel-pidfile'
,
_
=
parser
.
add_argument_group
(
'routing'
).
add_argument
help
=
'Specify a file to write our process id to'
)
_
(
'--babel-pidfile'
,
metavar
=
'PID'
,
_
(
'--babel-verb'
,
default
=
0
,
help
=
"Specify a file to write our process id to"
help
=
'Babel verbosity'
)
" (option -I of Babel)."
)
_
(
'--babel-verb'
,
default
=
0
,
metavar
=
'LEVEL'
,
help
=
"Log level of Babel (option -d of Babel)."
)
_
(
'--hello'
,
type
=
int
,
default
=
15
,
_
(
'--hello'
,
type
=
int
,
default
=
15
,
help
=
'Hello interval for babel, in seconds'
)
help
=
"Hello interval in seconds, for both wired and wireless"
" connections. OpenVPN ping-exit option is set to 4 times the"
" hello interval. It takes between 3 and 4 times the"
" hello interval for Babel to re-establish connection with a"
" node for which the direct connection has been cut."
)
_
(
'-w'
,
'--wireless'
,
action
=
'store_true'
,
_
(
'-w'
,
'--wireless'
,
action
=
'store_true'
,
help
=
'''Set all interfaces to be treated as wireless interfaces
help
=
"Assume all interfaces are wireless (option -w of Babel)."
)
for the routing protocol'''
)
# Tunnel options
_
=
parser
.
add_argument_group
(
'tunnelling'
).
add_argument
_
(
'--encrypt'
,
action
=
'store_true'
,
_
(
'--encrypt'
,
action
=
'store_true'
,
help
=
'specify that tunnels should be encrypted'
)
help
=
'Specify that tunnels should be encrypted.'
)
_
(
'--pp'
,
nargs
=
2
,
action
=
'append'
,
_
(
'--pp'
,
nargs
=
2
,
action
=
'append'
,
metavar
=
(
'PORT'
,
'PROTO'
),
help
=
'Port and protocol to be used by other peers to connect'
)
help
=
"Port and protocol to be announced to other peers, ordered by"
" preference. For each protocol (either udp or tcp), start one"
" openvpn server on the first given port."
" (default: --pp 1194 udp --pp 1194 tcp)"
)
_
(
'--dh'
,
required
=
True
,
_
(
'--dh'
,
required
=
True
,
help
=
'Path to dh file'
)
help
=
'File containing Diffie-Hellman parameters in .pem format'
)
_
(
'--ca'
,
required
=
True
,
_
(
'--ca'
,
required
=
True
,
help
=
parser
.
_ca_help
)
help
=
'Path to the certificate authority file'
)
_
(
'--cert'
,
required
=
True
,
_
(
'--cert'
,
required
=
True
,
help
=
'Path to the certificate file'
)
help
=
"Local peer's signed certificate in .pem format."
" Common name defines the allocated prefix in the network."
)
_
(
'--key'
,
required
=
True
,
_
(
'--key'
,
required
=
True
,
help
=
'Path to the private key file'
)
help
=
"Local peer's private key in .pem format."
)
_
(
'--connection-count'
,
default
=
20
,
type
=
int
,
_
(
'--connection-count'
,
default
=
20
,
type
=
int
,
help
=
'Number of tunnels'
)
help
=
"Maximum number of accepted clients per OpenVPN server."
" Also represents the average number of tunnels to peers."
)
_
(
'--tunnel-refresh'
,
default
=
300
,
type
=
int
,
_
(
'--tunnel-refresh'
,
default
=
300
,
type
=
int
,
help
=
'time (seconds) to wait before changing the connections'
)
help
=
"Interval in seconds between two tunnel refresh: the worst"
" tunnel is closed if the number of client tunnels has reached"
" its maximum number (half of connection-count)."
)
# Openvpn options
_
(
'openvpn_args'
,
nargs
=
argparse
.
REMAINDER
,
_
(
'openvpn_args'
,
nargs
=
argparse
.
REMAINDER
,
help
=
"Common OpenVPN options"
)
help
=
"Use pseudo-argument '--' to forward positional arguments as extra"
" arguments to both server and client OpenVPN subprocesses."
)
return
parser
.
parse_args
()
return
parser
.
parse_args
()
...
...
setup.py
View file @
212242ff
...
@@ -8,6 +8,7 @@ Environment :: Console
...
@@ -8,6 +8,7 @@ Environment :: Console
License :: OSI Approved :: GNU General Public License (GPL)
License :: OSI Approved :: GNU General Public License (GPL)
Natural Language :: English
Natural Language :: English
Operating System :: POSIX :: Linux
Operating System :: POSIX :: Linux
Programming Language :: Python :: 2.6
Programming Language :: Python :: 2.7
Programming Language :: Python :: 2.7
Topic :: Internet
Topic :: Internet
Topic :: System :: Networking
Topic :: System :: Networking
...
...
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