Move OpenVPN and StrongSwan entrypoint to separate Docker images
This commit is contained in:
parent
f5024edaec
commit
a42db0219c
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:20.04 as base
|
||||
FROM ubuntu:20.04
|
||||
ENV container docker
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV LC_ALL C.UTF-8
|
||||
|
@ -1,4 +1,5 @@
|
||||
include README.md
|
||||
include pinecrypt/server/templates/*.conf
|
||||
include pinecrypt/server/templates/mail/*.md
|
||||
include pinecrypt/server/builder/overlay/usr/bin/pinecrypt.server-*
|
||||
include pinecrypt/server/builder/overlay/etc/uci-defaults/*
|
||||
|
@ -1,15 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import os
|
||||
import sys
|
||||
from pinecrypt.server import db
|
||||
|
||||
# This implements OCSP like functionality
|
||||
|
||||
obj = db.certificates.find_one({
|
||||
# TODO: use digest instead
|
||||
"serial_number": "%x" % int(os.environ["tls_serial_0"]),
|
||||
"status":"signed",
|
||||
})
|
||||
|
||||
if not obj:
|
||||
sys.exit(1)
|
@ -1,28 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import os
|
||||
import sys
|
||||
from pinecrypt.server import db
|
||||
from datetime import datetime
|
||||
|
||||
operation, addr = sys.argv[1:3]
|
||||
if operation == "delete":
|
||||
pass
|
||||
else:
|
||||
common_name = sys.argv[3]
|
||||
db.certificates.update_one({
|
||||
# TODO: use digest instead
|
||||
"serial_number": "%x" % int(os.environ["tls_serial_0"]),
|
||||
"status":"signed",
|
||||
}, {
|
||||
"$set": {
|
||||
"last_seen": datetime.utcnow(),
|
||||
"instance": os.environ["instance"],
|
||||
"remote": {
|
||||
"port": int(os.environ["untrusted_port"]),
|
||||
"addr": os.environ["untrusted_ip"],
|
||||
}
|
||||
},
|
||||
"$addToSet": {
|
||||
"ip": addr
|
||||
}
|
||||
})
|
@ -1,31 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import sys
|
||||
import os
|
||||
from pinecrypt.server import db
|
||||
from datetime import datetime
|
||||
|
||||
addrs = set()
|
||||
for key, value in os.environ.items():
|
||||
if key.startswith("PLUTO_PEER_SOURCEIP"):
|
||||
addrs.add(value)
|
||||
|
||||
with open("/instance") as fh:
|
||||
instance = fh.read().strip()
|
||||
|
||||
db.certificates.update_one({
|
||||
"distinguished_name": os.environ["PLUTO_PEER_ID"],
|
||||
"status":"signed",
|
||||
}, {
|
||||
"$set": {
|
||||
"last_seen": datetime.utcnow(),
|
||||
"instance": instance,
|
||||
"remote": {
|
||||
"addr": os.environ["PLUTO_PEER"]
|
||||
}
|
||||
},
|
||||
"$addToSet": {
|
||||
"ip": {
|
||||
"$each": list(addrs)
|
||||
}
|
||||
}
|
||||
})
|
@ -169,7 +169,7 @@ def authenticate(optional=False):
|
||||
user, passwd = b64decode(token).decode("utf-8").split(":", 1)
|
||||
|
||||
if "ldap" in const.AUTHENTICATION_BACKENDS:
|
||||
upn = "%s@%s" % (user, const.KERBEROS_REALM)
|
||||
upn = ("%s@%s" % (user, const.KERBEROS_REALM)).lower()
|
||||
click.echo("Connecting to %s as %s" % (const.LDAP_AUTHENTICATION_URI, upn))
|
||||
conn = ldap.initialize(const.LDAP_AUTHENTICATION_URI, bytes_mode=False)
|
||||
conn.set_option(ldap.OPT_REFERRALS, 0)
|
||||
@ -185,9 +185,9 @@ def authenticate(optional=False):
|
||||
raise
|
||||
except ldap.INVALID_CREDENTIALS:
|
||||
logger.critical("LDAP bind authentication failed for user %s from %s",
|
||||
repr(user), req.context["remote"]["addr"])
|
||||
repr(upn), req.context["remote"]["addr"])
|
||||
raise falcon.HTTPUnauthorized(
|
||||
description="Please authenticate with %s domain account username" % const.DOMAIN,
|
||||
description="Please authenticate with %s domain account username" % const.KERBEROS_REALM,
|
||||
challenges=["Basic"])
|
||||
|
||||
req.context["ldap_conn"] = conn
|
||||
|
@ -81,6 +81,7 @@ def self_enroll(skip_notify=False):
|
||||
cert, buf = sign(mongo_id=id, skip_notify=skip_notify, overwrite=True,
|
||||
profile="Gateway", namespace=const.AUTHORITY_NAMESPACE)
|
||||
|
||||
os.umask(0o133)
|
||||
with open(const.SELF_CERT_PATH + ".part", "wb") as fh:
|
||||
fh.write(buf)
|
||||
os.rename(const.SELF_CERT_PATH + ".part", const.SELF_CERT_PATH)
|
||||
|
@ -20,7 +20,9 @@ import pytz
|
||||
from asn1crypto import pem, x509
|
||||
from certbuilder import CertificateBuilder, pem_armor_certificate
|
||||
from datetime import datetime, timedelta
|
||||
from jinja2 import Environment, PackageLoader
|
||||
from oscrypto import asymmetric
|
||||
from math import log, ceil
|
||||
from pinecrypt.server import const, mongolog, mailer, db
|
||||
from pinecrypt.server.middleware import NormalizeMiddleware, PrometheusEndpoint
|
||||
from pinecrypt.server.common import cn_to_dn, generate_serial
|
||||
@ -340,8 +342,8 @@ def pinecone_provision():
|
||||
with open(const.AUTHORITY_PRIVATE_KEY_PATH + ".part", "wb") as f:
|
||||
f.write(obj["key"])
|
||||
|
||||
# Set permission bits to 640
|
||||
os.umask(0o137)
|
||||
# Set permission bits to 644
|
||||
os.umask(0o133)
|
||||
with open(const.AUTHORITY_CERTIFICATE_PATH + ".part", "wb") as f:
|
||||
f.write(obj["cert"])
|
||||
|
||||
@ -371,6 +373,71 @@ def pinecone_provision():
|
||||
}
|
||||
})
|
||||
|
||||
# Separate pushed subnets by address family
|
||||
push4 = set()
|
||||
push6 = set()
|
||||
for subnet in const.PUSH_SUBNETS:
|
||||
if subnet.version == 4:
|
||||
push4.add(subnet)
|
||||
elif subnet.version == 6:
|
||||
if not const.CLIENT_SUBNET6:
|
||||
raise ValueError("Can't push IPv6 routes if no IPv6 client subnet is configured")
|
||||
push6.add(subnet)
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
|
||||
# Generate OpenVPN configurations
|
||||
click.echo("Generating OpenVPN configuration files...")
|
||||
from pinecrypt.server import config
|
||||
ctx = {
|
||||
"authority_namespace": const.AUTHORITY_NAMESPACE,
|
||||
"push4": push4,
|
||||
"push6": push6,
|
||||
"openvpn_tls_version_min": config.get("Globals", "OPENVPN_TLS_VERSION_MIN")["value"],
|
||||
"openvpn_tls_ciphersuites": config.get("Globals", "OPENVPN_TLS_CIPHERSUITES")["value"],
|
||||
"openvpn_tls_cipher": config.get("Globals", "OPENVPN_TLS_CIPHER")["value"],
|
||||
"openvpn_cipher": config.get("Globals", "OPENVPN_CIPHER")["value"],
|
||||
"openvpn_auth": config.get("Globals", "OPENVPN_AUTH")["value"],
|
||||
"strongswan_dhgroup": config.get("Globals", "STRONGSWAN_DHGROUP")["value"],
|
||||
"strongswan_ike": config.get("Globals", "STRONGSWAN_IKE")["value"],
|
||||
"strongswan_esp": config.get("Globals", "STRONGSWAN_ESP")["value"],
|
||||
}
|
||||
|
||||
env = Environment(loader=PackageLoader("pinecrypt.server", "templates"))
|
||||
os.umask(0o133)
|
||||
|
||||
d = ceil(log(const.CLIENT_SUBNET_SLOT_COUNT) / log(2))
|
||||
for slot, proto in enumerate(["udp", "tcp"]):
|
||||
ctx["proto"] = proto
|
||||
ctx["slot4"] = list(const.CLIENT_SUBNET4.subnets(d))[slot]
|
||||
ctx["slot6"] = list(const.CLIENT_SUBNET6.subnets(d))[slot] if const.CLIENT_SUBNET6 else None
|
||||
with open("/server-secrets/openvpn-%s.conf" % proto, "w") as fh:
|
||||
fh.write(env.get_template("openvpn.conf").render(ctx))
|
||||
|
||||
# Merged variants for StrongSwan
|
||||
ctx["push"] = ctx["push4"].union(ctx["push6"])
|
||||
|
||||
# Generate StrongSwan config
|
||||
click.echo("Generating StrongSwan configuration files...")
|
||||
slot += 1
|
||||
ctx["slot4"] = list(const.CLIENT_SUBNET4.subnets(d))[slot]
|
||||
ctx["slot6"] = list(const.CLIENT_SUBNET6.subnets(d))[slot] if const.CLIENT_SUBNET6 else []
|
||||
with open("/server-secrets/ipsec.conf", "w") as fh:
|
||||
fh.write(env.get_template("ipsec.conf").render(ctx))
|
||||
|
||||
# Why do you do this StrongSwan?! You will parse the cert anyway,
|
||||
# why do I need to distinguish ECDSA vs RSA in config?!
|
||||
with open(const.SELF_CERT_PATH, "rb") as fh:
|
||||
certificate_buf = fh.read()
|
||||
header, _, certificate_der_bytes = pem.unarmor(certificate_buf)
|
||||
certificate = x509.Certificate.load(certificate_der_bytes)
|
||||
public_key = asymmetric.load_public_key(certificate["tbs_certificate"]["subject_public_key_info"])
|
||||
with open("/server-secrets/ipsec.secrets", "w") as fh:
|
||||
fh.write(": %s %s\n" % (
|
||||
"ECDSA" if public_key.algorithm == "ec" else "RSA",
|
||||
const.SELF_KEY_PATH
|
||||
))
|
||||
|
||||
# TODO: use this task to send notification emails maybe?
|
||||
click.echo("Finished starting up")
|
||||
sleep(86400)
|
||||
@ -491,173 +558,6 @@ def pinecone_session(): pass
|
||||
def entry_point(): pass
|
||||
|
||||
|
||||
@click.command("openvpn", help="Start OpenVPN server process")
|
||||
@click.option("--local", "-l", default="0.0.0.0", help="OpenVPN listening address, defaults to all interfaces")
|
||||
@click.option("--proto", "-t", default="udp", type=click.Choice(["udp", "tcp"]), help="OpenVPN transport protocol, UDP by default")
|
||||
@click.option("--client-subnet-slot", "-s", type=int, help="Client subnet slot index")
|
||||
@waitfile(const.SELF_CERT_PATH)
|
||||
def pinecone_serve_openvpn(local, proto, client_subnet_slot):
|
||||
from pinecrypt.server import config
|
||||
# TODO: Generate (per-client configs) from MongoDB
|
||||
executable = "/usr/sbin/openvpn"
|
||||
|
||||
args = executable,
|
||||
slot4 = const.CLIENT_SUBNET4_SLOTS[client_subnet_slot]
|
||||
args += "--server", str(slot4.network_address), str(slot4.netmask),
|
||||
if const.CLIENT_SUBNET6:
|
||||
args += "--server-ipv6", str(const.CLIENT_SUBNET6_SLOTS[client_subnet_slot]),
|
||||
args += "--local", local
|
||||
|
||||
# Support only two modes TCP 443 and UDP 1194
|
||||
if proto == "tcp":
|
||||
args += "--dev", "tuntcp0",
|
||||
args += "--port-share", "127.0.0.1", "1443",
|
||||
args += "--proto", "tcp-server",
|
||||
args += "--port", "443",
|
||||
args += "--socket-flags", "TCP_NODELAY",
|
||||
args += "--management", "127.0.0.1", "7506",
|
||||
instance = "%s-openvpn-tcp-443" % const.FQDN
|
||||
else:
|
||||
args += "--dev", "tunudp0",
|
||||
args += "--proto", "udp",
|
||||
args += "--port", "1194",
|
||||
args += "--management", "127.0.0.1", "7505",
|
||||
instance = "%s-openvpn-udp-1194" % const.FQDN
|
||||
args += "--setenv", "instance", instance
|
||||
db.certificates.update_many({
|
||||
"instance": instance
|
||||
}, {
|
||||
"$unset": {
|
||||
"ip": "",
|
||||
"instance": "",
|
||||
}
|
||||
})
|
||||
|
||||
# Send keep alive packets, mainly for UDP
|
||||
args += "--keepalive", "60", "120",
|
||||
|
||||
args += "--opt-verify",
|
||||
|
||||
args += "--key", const.SELF_KEY_PATH
|
||||
args += "--cert", const.SELF_CERT_PATH
|
||||
args += "--ca", const.AUTHORITY_CERTIFICATE_PATH
|
||||
|
||||
if const.PUSH_SUBNETS:
|
||||
args += "--push", "route-metric 1000"
|
||||
for subnet in const.PUSH_SUBNETS:
|
||||
if subnet.version == 4:
|
||||
args += "--push", "route %s %s" % (subnet.network_address, subnet.netmask),
|
||||
elif subnet.version == 6:
|
||||
if not const.CLIENT_SUBNET6:
|
||||
raise ValueError("Can't push IPv6 routes if no IPv6 client subnet is configured")
|
||||
args += "--push", "route-ipv6 %s" % subnet
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
|
||||
# TODO: Figure out how to do dhparam without blocking initially
|
||||
if os.path.exists(const.DHPARAM_PATH):
|
||||
args += "--dh", const.DHPARAM_PATH
|
||||
else:
|
||||
args += "--dh", "none"
|
||||
|
||||
# For more info see: openvpn --show-tls
|
||||
args += "--tls-version-min", config.get("Globals", "OPENVPN_TLS_VERSION_MIN")["value"]
|
||||
args += "--tls-ciphersuites", config.get("Globals", "OPENVPN_TLS_CIPHERSUITES")["value"], # Used by TLS 1.3
|
||||
args += "--tls-cipher", config.get("Globals", "OPENVPN_TLS_CIPHER")["value"], # Used by TLS 1.2
|
||||
|
||||
# Data channel encryption parameters
|
||||
# TODO: Rename to --data-cipher when OpenVPN 2.5 becomes available
|
||||
args += "--cipher", config.get("Globals", "OPENVPN_CIPHER")["value"]
|
||||
args += "--auth", config.get("Globals", "OPENVPN_AUTH")["value"]
|
||||
|
||||
# Just to sanity check ourselves
|
||||
args += "--tls-cert-profile", "preferred",
|
||||
|
||||
# Disable cipher negotiation since we know what we want
|
||||
args += "--ncp-disable",
|
||||
|
||||
args += "--script-security", "2",
|
||||
args += "--learn-address", "/helpers/openvpn-learn-address.py"
|
||||
args += "--client-connect", "/helpers/openvpn-client-connect.py"
|
||||
args += "--verb", "0",
|
||||
|
||||
logger.info("Executing: %s" % (" ".join(args)))
|
||||
os.execv(executable, args)
|
||||
|
||||
|
||||
@click.command("strongswan", help="Start StrongSwan")
|
||||
@click.option("--client-subnet-slot", "-s", type=int, help="Client subnet slot index")
|
||||
@waitfile(const.SELF_CERT_PATH)
|
||||
def pinecone_serve_strongswan(client_subnet_slot):
|
||||
from pinecrypt.server import config
|
||||
slots = []
|
||||
slots.append(const.CLIENT_SUBNET4_SLOTS[client_subnet_slot])
|
||||
if const.CLIENT_SUBNET6:
|
||||
slots.append(const.CLIENT_SUBNET6_SLOTS[client_subnet_slot])
|
||||
|
||||
with open("/etc/ipsec.conf", "w") as fh:
|
||||
fh.write("config setup\n")
|
||||
fh.write(" strictcrlpolicy=yes\n")
|
||||
fh.write(" charondebug=\"cfg 2\"\n")
|
||||
|
||||
fh.write("\n")
|
||||
fh.write("ca authority\n")
|
||||
fh.write(" auto=add\n")
|
||||
fh.write(" cacert=%s\n" % const.AUTHORITY_CERTIFICATE_PATH)
|
||||
fh.write("\n")
|
||||
fh.write("conn s2c\n")
|
||||
fh.write(" auto=add\n")
|
||||
fh.write(" keyexchange=ikev2\n")
|
||||
|
||||
fh.write(" left=%s\n" % const.AUTHORITY_NAMESPACE)
|
||||
fh.write(" leftsendcert=always\n")
|
||||
fh.write(" leftallowany=yes\n") # For load-balancing
|
||||
fh.write(" leftcert=%s\n" % const.SELF_CERT_PATH)
|
||||
if const.PUSH_SUBNETS:
|
||||
fh.write(" leftsubnet=%s\n" % ",".join([str(j) for j in const.PUSH_SUBNETS]))
|
||||
fh.write(" leftupdown=/helpers/updown.py\n")
|
||||
|
||||
fh.write(" right=%any\n")
|
||||
fh.write(" rightsourceip=%s\n" % ",".join([str(j) for j in slots]))
|
||||
fh.write(" ike=%s!\n" % config.get("Globals", "STRONGSWAN_IKE")["value"])
|
||||
fh.write(" esp=%s!\n" % config.get("Globals", "STRONGSWAN_ESP")["value"])
|
||||
with open("/etc/ipsec.conf") as fh:
|
||||
print(fh.read())
|
||||
|
||||
# Why do you do this StrongSwan?! You will parse the cert anyway,
|
||||
# why do I need to distinguish ECDSA vs RSA in config?!
|
||||
with open(const.SELF_CERT_PATH, "rb") as fh:
|
||||
certificate_buf = fh.read()
|
||||
header, _, certificate_der_bytes = pem.unarmor(certificate_buf)
|
||||
certificate = x509.Certificate.load(certificate_der_bytes)
|
||||
public_key = asymmetric.load_public_key(certificate["tbs_certificate"]["subject_public_key_info"])
|
||||
with open("/etc/ipsec.secrets", "w") as fh:
|
||||
fh.write(": %s %s\n" % (
|
||||
"ECDSA" if public_key.algorithm == "ec" else "RSA",
|
||||
const.SELF_KEY_PATH
|
||||
))
|
||||
executable = "/usr/sbin/ipsec"
|
||||
args = executable, "start", "--nofork"
|
||||
logger.info("Executing: %s" % (" ".join(args)))
|
||||
instance = "%s-ipsec" % const.FQDN
|
||||
|
||||
db.certificates.update_many({
|
||||
"instance": instance
|
||||
}, {
|
||||
"$unset": {
|
||||
"ip": "",
|
||||
"instance": "",
|
||||
}
|
||||
})
|
||||
|
||||
# TODO: Find better way to push env vars to updown script
|
||||
with open("/instance", "w") as fh:
|
||||
fh.write(instance)
|
||||
os.execv(executable, args)
|
||||
|
||||
|
||||
pinecone_serve.add_command(pinecone_serve_openvpn)
|
||||
pinecone_serve.add_command(pinecone_serve_strongswan)
|
||||
pinecone_serve.add_command(pinecone_serve_backend)
|
||||
pinecone_serve.add_command(pinecone_serve_ocsp_responder)
|
||||
pinecone_serve.add_command(pinecone_serve_events)
|
||||
|
@ -6,7 +6,6 @@ import socket
|
||||
import sys
|
||||
from datetime import timedelta
|
||||
from ipaddress import ip_network
|
||||
from math import log, ceil
|
||||
|
||||
RE_USERNAME = r"^[a-z][a-z0-9]+$"
|
||||
RE_FQDN = r"^(([a-z0-9]|[a-z0-9][a-z0-9\-_]*[a-z0-9])\.)+([a-z0-9]|[a-z0-9][a-z0-9\-_]*[a-z0-9])?$"
|
||||
@ -46,11 +45,11 @@ CURVE_NAME = "secp384r1"
|
||||
# Kerberos-like clock skew tolerance
|
||||
CLOCK_SKEW_TOLERANCE = timedelta(minutes=5)
|
||||
|
||||
AUTHORITY_PRIVATE_KEY_PATH = "/var/lib/certidude/authority-secrets/ca_key.pem"
|
||||
AUTHORITY_CERTIFICATE_PATH = "/var/lib/certidude/server-secrets/ca_cert.pem"
|
||||
SELF_CERT_PATH = "/var/lib/certidude/server-secrets/self_cert.pem"
|
||||
SELF_KEY_PATH = "/var/lib/certidude/server-secrets/self_key.pem"
|
||||
DHPARAM_PATH = "/var/lib/certidude/server-secrets/dhparam.pem"
|
||||
AUTHORITY_PRIVATE_KEY_PATH = "/authority-secrets/ca_key.pem"
|
||||
AUTHORITY_CERTIFICATE_PATH = "/server-secrets/ca_cert.pem"
|
||||
SELF_CERT_PATH = "/server-secrets/self_cert.pem"
|
||||
SELF_KEY_PATH = "/server-secrets/self_key.pem"
|
||||
DHPARAM_PATH = "/server-secrets/dhparam.pem"
|
||||
BUILDER_TARBALLS = ""
|
||||
|
||||
FQDN = socket.getfqdn()
|
||||
@ -114,7 +113,7 @@ TOKEN_OVERWRITE_PERMITTED = os.getenv("TOKEN_OVERWRITE_PERMITTED")
|
||||
AUTHENTICATION_BACKENDS = set(["ldap"])
|
||||
MAIL_SUFFIX = os.getenv("MAIL_SUFFIX")
|
||||
|
||||
KERBEROS_KEYTAB = os.getenv("KERBEROS_KEYTAB", "/var/lib/certidude/server-secrets/krb5.keytab")
|
||||
KERBEROS_KEYTAB = os.getenv("KERBEROS_KEYTAB", "/server-secrets/krb5.keytab")
|
||||
KERBEROS_REALM = os.getenv("KERBEROS_REALM")
|
||||
LDAP_AUTHENTICATION_URI = os.getenv("LDAP_AUTHENTICATION_URI")
|
||||
LDAP_GSSAPI_CRED_CACHE = os.getenv("LDAP_GSSAPI_CRED_CACHE", "/run/certidude/krb5cc")
|
||||
@ -158,13 +157,9 @@ REQUEST_SUBMISSION_ALLOWED = os.getenv("REQUEST_SUBMISSION_ALLOWED")
|
||||
REVOCATION_LIST_LIFETIME = os.getenv("REVOCATION_LIST_LIFETIME")
|
||||
|
||||
PUSH_SUBNETS = [ip_network(j) for j in os.getenv("PUSH_SUBNETS", "").replace(" ", ",").split(",") if j]
|
||||
|
||||
CLIENT_SUBNET4 = ip_network(os.getenv("CLIENT_SUBNET4", "192.168.33.0/24"))
|
||||
CLIENT_SUBNET6 = ip_network(os.getenv("CLIENT_SUBNET6")) if os.getenv("CLIENT_SUBNET6") else None
|
||||
CLIENT_SUBNET_SLOT_COUNT = int(os.getenv("CLIENT_SUBNET_COUNT", 4))
|
||||
divisions = ceil(log(CLIENT_SUBNET_SLOT_COUNT) / log(2))
|
||||
CLIENT_SUBNET4_SLOTS = list(CLIENT_SUBNET4.subnets(divisions))
|
||||
CLIENT_SUBNET6_SLOTS = list(CLIENT_SUBNET6.subnets(divisions)) if CLIENT_SUBNET6 else []
|
||||
|
||||
if CLIENT_SUBNET4.netmask == str("255.255.255.255"):
|
||||
raise ValueError("Invalid client subnet specification: %s" % CLIENT_SUBNET4)
|
||||
|
21
pinecrypt/server/templates/ipsec.conf
Normal file
21
pinecrypt/server/templates/ipsec.conf
Normal file
@ -0,0 +1,21 @@
|
||||
config setup
|
||||
strictcrlpolicy=yes
|
||||
charondebug="cfg 2"
|
||||
|
||||
ca authority
|
||||
auto=add
|
||||
cacert=/server-secrets/ca_cert.pem
|
||||
|
||||
conn s2c
|
||||
auto=add
|
||||
keyexchange=ikev2
|
||||
left={{ authority_namespace }}
|
||||
leftsendcert=always
|
||||
leftallowany=yes
|
||||
leftcert=/server-secrets/self_cert.pem
|
||||
leftsubnet={% for subnet in push %}{{ subnet }},{% endfor %}
|
||||
leftupdown=/helpers/updown.py
|
||||
right=%any
|
||||
rightsourceip={{ slot4 }}{% if slot6 %},{{ slot6 }}{% endif %}
|
||||
ike={{ strongswan_ike }}!
|
||||
esp={{ strongswan_esp }}!
|
69
pinecrypt/server/templates/openvpn.conf
Normal file
69
pinecrypt/server/templates/openvpn.conf
Normal file
@ -0,0 +1,69 @@
|
||||
{% if proto == "udp" %}
|
||||
dev tun0
|
||||
proto udp
|
||||
port 1194
|
||||
management 127.0.0.1 7505
|
||||
setenv service openvpn-udp
|
||||
{% else %}
|
||||
dev tun1
|
||||
port-share 127.0.0.1 1443
|
||||
proto tcp-server
|
||||
port 443
|
||||
socket-flags TCP_NODELAY
|
||||
management 127.0.0.1 7506
|
||||
setenv service openvpn-tcp
|
||||
{% endif %}
|
||||
|
||||
# Client subnets
|
||||
server {{ slot4.network_address }} {{ slot4.netmask }}
|
||||
{% if slot6 %}
|
||||
server-ipv6 {{ slot6 }}
|
||||
{% endif %}
|
||||
topology subnet
|
||||
|
||||
# Bind to all interfaces
|
||||
local 0.0.0.0
|
||||
|
||||
# Send keep alive packets, mainly for UDP
|
||||
keepalive 60 120
|
||||
|
||||
opt-verify
|
||||
|
||||
# Keypairs
|
||||
key /server-secrets/self_key.pem
|
||||
cert /server-secrets/self_cert.pem
|
||||
ca /server-secrets/ca_cert.pem
|
||||
|
||||
# Push subnets
|
||||
{% if push %}
|
||||
push "route-metric 10002
|
||||
{% endif %}
|
||||
{% for subnet in push4 %}
|
||||
push "route {{ subnet.network_address }} {{ subnet.netmask }}"
|
||||
{% endfor %}
|
||||
{% for subnet in push6 %}
|
||||
push "route-ipv6 {{ subnet }}"
|
||||
{% endfor %}
|
||||
|
||||
# DH parameters file
|
||||
dh none
|
||||
#dhparam.pem
|
||||
|
||||
# Control channel encryption parameterss
|
||||
# For more info see: openvpn --show-tls
|
||||
tls-version-min {{ openvpn_tls_version_min }}
|
||||
tls-ciphersuites {{ openvpn_tls_ciphersuites }} # Used by TLS 1.3
|
||||
tls-cipher {{ openvpn_tls_cipher }} # Used by TLS 1.2
|
||||
|
||||
# Data channel encryption parameters
|
||||
cipher {{ openvpn_cipher }}
|
||||
auth {{ openvpn_auth }}
|
||||
|
||||
# Just to sanity check ourselves
|
||||
tls-cert-profile preferred
|
||||
|
||||
script-security 2
|
||||
learn-address /helpers/learn-address.py
|
||||
client-connect /helpers/client-connect.py
|
||||
#verb 0
|
||||
|
Loading…
Reference in New Issue
Block a user