Merge branch 'develop' into 'master'
Release See merge request paul/certman!1
This commit is contained in:
commit
c9c88d0610
7 changed files with 135 additions and 61 deletions
|
@ -27,7 +27,7 @@ format:
|
||||||
# we use tags="dev" so there is no dependency on the prebuilt assets yet
|
# we use tags="dev" so there is no dependency on the prebuilt assets yet
|
||||||
- go get -tags="dev" -v $(go list ./... | grep -v /vendor/) # get missing dependencies
|
- go get -tags="dev" -v $(go list ./... | grep -v /vendor/) # get missing dependencies
|
||||||
- go fmt $(go list ./... | grep -v /vendor/)
|
- go fmt $(go list ./... | grep -v /vendor/)
|
||||||
- go vet $(go list ./... | grep -v /vendor/)
|
- go vet -tags="dev" $(go list ./... | grep -v /vendor/)
|
||||||
- go test -tags="dev" -race $(go list ./... | grep -v /vendor/) -v -coverprofile .testCoverage.txt
|
- go test -tags="dev" -race $(go list ./... | grep -v /vendor/) -v -coverprofile .testCoverage.txt
|
||||||
# Use coverage parsing regex: ^coverage:\s(\d+(?:\.\d+)?%)
|
# Use coverage parsing regex: ^coverage:\s(\d+(?:\.\d+)?%)
|
||||||
|
|
||||||
|
@ -87,4 +87,4 @@ build_image:
|
||||||
- docker build -t $CI_REGISTRY_IMAGE:${CI_COMMIT_REF_NAME#v} .
|
- docker build -t $CI_REGISTRY_IMAGE:${CI_COMMIT_REF_NAME#v} .
|
||||||
- docker push $CI_REGISTRY_IMAGE:${CI_COMMIT_REF_NAME#v}
|
- docker push $CI_REGISTRY_IMAGE:${CI_COMMIT_REF_NAME#v}
|
||||||
# only:
|
# only:
|
||||||
# - tags
|
# - tags
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM golang:1.9
|
FROM golang:1.10
|
||||||
|
|
||||||
WORKDIR /go/src/git.klink.asia/paul/certman
|
WORKDIR /go/src/git.klink.asia/paul/certman
|
||||||
ADD . .
|
ADD . .
|
||||||
|
@ -10,13 +10,16 @@ RUN \
|
||||||
|
|
||||||
FROM scratch
|
FROM scratch
|
||||||
ENV \
|
ENV \
|
||||||
APP_KEY="" \
|
|
||||||
OAUTH2_CLIENT_ID="" \
|
OAUTH2_CLIENT_ID="" \
|
||||||
OAUTH2_CLIENT_SECRET="" \
|
OAUTH2_CLIENT_SECRET="" \
|
||||||
OAUTH2_AUTH_URL="https://gitlab.example.com/oauth/authorize" \
|
OAUTH2_AUTH_URL="https://gitlab.example.com/oauth/authorize" \
|
||||||
OAUTH2_TOKEN_URL="https://gitlab.example.com/oauth/token" \
|
OAUTH2_TOKEN_URL="https://gitlab.example.com/oauth/token" \
|
||||||
OAUTH2_REDIRECT_URL="https://certman.example.com/login/oauth2/redirect" \
|
OAUTH2_REDIRECT_URL="https://vpn.example.com/login/oauth2/redirect" \
|
||||||
USER_ENDPOINT="https://gitlab.example.com/api/v4/user" \
|
USER_ENDPOINT="https://gitlab.example.com/api/v4/user" \
|
||||||
|
VPN_DEV="tun" \
|
||||||
|
VPN_HOST="vpn.example.com" \
|
||||||
|
VPN_PORT="1194" \
|
||||||
|
VPN_PROTO="udp" \
|
||||||
APP_KEY=""
|
APP_KEY=""
|
||||||
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||||
COPY --from=0 /go/src/git.klink.asia/paul/certman/certman /
|
COPY --from=0 /go/src/git.klink.asia/paul/certman/certman /
|
||||||
|
|
23
README.md
23
README.md
|
@ -1,6 +1,8 @@
|
||||||
# Certman
|
# Certman
|
||||||
Certman is a simple certificate manager web service for OpenVPN.
|
Certman is a simple certificate manager web service for OpenVPN.
|
||||||
|
|
||||||
|
**For usage tips, please consult [`usage.md`](usage.md)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
### Binary
|
### Binary
|
||||||
There are prebuilt binary files for this application. They are statically
|
There are prebuilt binary files for this application. They are statically
|
||||||
|
@ -11,12 +13,14 @@ linked and have no additional dependencies. Supported plattforms are:
|
||||||
Simply download them from the "artifacts" section of this project.
|
Simply download them from the "artifacts" section of this project.
|
||||||
### Docker
|
### Docker
|
||||||
A prebuilt docker image (10MB) is available:
|
A prebuilt docker image (10MB) is available:
|
||||||
```bash
|
|
||||||
|
```
|
||||||
docker pull docker.klink.asia/paul/certman
|
docker pull docker.klink.asia/paul/certman
|
||||||
```
|
```
|
||||||
### From Source-Docker
|
### From Source-Docker
|
||||||
You can easily build your own docker image from source
|
You can easily build your own docker image from source
|
||||||
```bash
|
|
||||||
|
```
|
||||||
docker build -t docker.klink.asia/paul/certman .
|
docker build -t docker.klink.asia/paul/certman .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -35,4 +39,17 @@ variables:
|
||||||
* `OAUTH2_REDIRECT_URL` the redirect URL used by the app, usually the hostname suffixed by "/login/oauth2/redirect"
|
* `OAUTH2_REDIRECT_URL` the redirect URL used by the app, usually the hostname suffixed by "/login/oauth2/redirect"
|
||||||
* `USER_ENDPOINT` the URL to the Identity provider user endpoint, for gitlab this is "/api/v4/user". The "username" attribute of the returned JSON will used for authentication.
|
* `USER_ENDPOINT` the URL to the Identity provider user endpoint, for gitlab this is "/api/v4/user". The "username" attribute of the returned JSON will used for authentication.
|
||||||
* `APP_KEY` random ASCII string, 32 characters in length. Used for cookie generation.
|
* `APP_KEY` random ASCII string, 32 characters in length. Used for cookie generation.
|
||||||
* `APP_LISTEN` port and ip to listen on, e.g. `:8000` or `127.0.0.1:3000`
|
* `APP_LISTEN` port and ip to listen on, e.g. `:8000` or `127.0.0.1:3000`
|
||||||
|
* `VPN_DEV` which device is used by the network, either `tun` or `tap` (check server cfg)
|
||||||
|
* `VPN_HOST` Hostname or IP address of the server
|
||||||
|
* `VPN_PORT` Port of the VPN server
|
||||||
|
* `VPN_PROTO` Protocol of the VPN server, either `tcp` or `udp`
|
||||||
|
|
||||||
|
There are some files that need to be mounted inside the container:
|
||||||
|
|
||||||
|
* `/ca.crt` the certificate of the server PKI
|
||||||
|
* `/ca.key` the key of the server PKI, unencrypted
|
||||||
|
* `/ta.key` shared HMAC secret of server and client
|
||||||
|
* `/clients.json` the generated certificates for each client
|
||||||
|
|
||||||
|
There is an [`docker-compose.yml example`](docker-compose.yml.example) you can use as a base for your own docker-compose service.
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
{{ define "base" }}# Client configuration for {{ .User }}@{{ .Name }}
|
{{ define "base" }}# Client configuration for {{ .User }}@{{ .Name }}
|
||||||
client
|
client
|
||||||
dev tun
|
dev {{ .Dev }}
|
||||||
remote ovpn.oneofftech.xyz 443 udp
|
remote {{ .Host }} {{ .Port }} {{ .Proto }}
|
||||||
remote ovpn.oneofftech.xyz 443 tcp
|
|
||||||
resolv-retry infinite
|
resolv-retry infinite
|
||||||
nobind
|
nobind
|
||||||
persist-key
|
persist-key
|
||||||
|
@ -16,33 +15,8 @@ tls-version-min 1.2
|
||||||
;comp-lzo
|
;comp-lzo
|
||||||
verb 3
|
verb 3
|
||||||
|
|
||||||
route 172.31.1.100 255.255.255.255 net_gateway
|
|
||||||
|
|
||||||
<ca>
|
<ca>
|
||||||
-----BEGIN CERTIFICATE-----
|
{{ .CA | html }}</ca>
|
||||||
MIIDwDCCAqigAwIBAgIJAMvRC7FajlAOMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNV
|
|
||||||
BAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjETMBEGA1UE
|
|
||||||
CgwKT25lT2ZmVGVjaDEWMBQGA1UECwwNSVQgZGVwYXJ0bWVudDEXMBUGA1UEAwwO
|
|
||||||
Y2EtY2VydGlmaWNhdGUwHhcNMTgwMTI1MTM0NjI3WhcNMjMwMTI0MTM0NjI3WjB1
|
|
||||||
MQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4x
|
|
||||||
EzARBgNVBAoMCk9uZU9mZlRlY2gxFjAUBgNVBAsMDUlUIGRlcGFydG1lbnQxFzAV
|
|
||||||
BgNVBAMMDmNhLWNlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
|
||||||
CgKCAQEA5LzVrHqz33L5YiFs1HOZWvLht9yQ6+AxK1+RDZsx8490UEYvPnguyU/c
|
|
||||||
8NtaZPtWOg5Qvnh+0tHpLHV+3WbWyIObkix6b3U5EgR6Hgdf1zuzX7y/S2o7uPT1
|
|
||||||
zkCgIi9EQfy0IDIhIErsO0dOWndFt/cAfrMaOx0LV/kzr9bKdgg7WLQoVzUgawZq
|
|
||||||
ROScZUogaElISxC/C77YaGg9V5sV9qTa3uZ9DxuESzXLGMDx3DJMjH+Yu+nhJjoc
|
|
||||||
isSxK5qEnfqWJhZgJFTAY2BRbcMFMieVz/+UGk2GDZf1tpMZOQKxwrNibe4HO8zo
|
|
||||||
lfhX+H+sb4QZCdn30eUGstK/jJdQrQIDAQABo1MwUTAdBgNVHQ4EFgQU9UASoCXR
|
|
||||||
ountXC2vQ4s9BT5qGRYwHwYDVR0jBBgwFoAU9UASoCXRountXC2vQ4s9BT5qGRYw
|
|
||||||
DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA2YgYuFKMzoblpPf+
|
|
||||||
VcyFKAXC9IoOJFeoA8FWMLBy38FedpCP+aFtlnG5eSLB/Xy7rdJK+7ASrdbAsFMD
|
|
||||||
U6P2guqUix4veIBZK0WLGTLfRKHQiOUqNP1zZpWsdrwUoUjGOEt4iqG9PCcaANSg
|
|
||||||
mOfl/BK+MtuRevF6Ry2JAZDArUXrXXjNdRXKB7iNc3Sd5icII53OGXXtn1ehzZXL
|
|
||||||
djbdz4MZa1kbA1ZlJVaYCRzOS/F9kU2aQceO17foxI5BvnOkpONLXDZHs61/KtYu
|
|
||||||
5z7hJoH49+4iyWZuRgWT/sq36qpvu+/f48JPxzqV94Jp77Z9BocTIjdfqHM++X9h
|
|
||||||
Yo95ZQ==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
</ca>
|
|
||||||
|
|
||||||
<cert>
|
<cert>
|
||||||
{{ .Cert | html }}</cert>
|
{{ .Cert | html }}</cert>
|
||||||
|
@ -51,26 +25,5 @@ Yo95ZQ==
|
||||||
{{ .Key | html }}</key>
|
{{ .Key | html }}</key>
|
||||||
|
|
||||||
<tls-auth>
|
<tls-auth>
|
||||||
#
|
{{ .TA | html }}</tls-auth>
|
||||||
# 2048 bit OpenVPN static key
|
|
||||||
#
|
|
||||||
-----BEGIN OpenVPN Static key V1-----
|
|
||||||
187be23c2b3b0a6a9d79bc5b5c95b70b
|
|
||||||
b43b6b303e7c00eb75121d68df470ea3
|
|
||||||
3cdd0ddedc273f5412f181709890ea32
|
|
||||||
7086cbc5b21bbaf3dd231d115b5ba986
|
|
||||||
1b1aee31bff9be5f6c6f6dd490d593a1
|
|
||||||
eec50bb866558c6b2c6fe62ebfe125d9
|
|
||||||
34b7115e72d94ce08cc9e1c4e8ccdbfe
|
|
||||||
a5ee19ac0aec60da63df881e3c2e7d4d
|
|
||||||
9c4f167ec1b46309f17c16c36683780b
|
|
||||||
bed7551ad7a3d526c19014567370122e
|
|
||||||
98ae0ae7fd83a8a6de09883fcc181b36
|
|
||||||
a8465c0deda7a345ec3d16a4daf3fbf5
|
|
||||||
23dc36a48e679c653b3cfc6dbaa150a7
|
|
||||||
7ace46081d2c3712ce655f4b8211f674
|
|
||||||
4d4688c2b3828f9208a80bf71e6e4554
|
|
||||||
ae09b91154a435995439ad576fcc72c1
|
|
||||||
-----END OpenVPN Static key V1-----
|
|
||||||
</tls-auth>
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
31
docker-compose.yml.example
Normal file
31
docker-compose.yml.example
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
networks:
|
||||||
|
web:
|
||||||
|
external:
|
||||||
|
name: reverseproxy_web
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: docker.klink.asia/paul/certman:latest
|
||||||
|
environment:
|
||||||
|
- "OAUTH2_CLIENT_ID=setme"
|
||||||
|
- "OAUTH2_CLIENT_SECRET=setme"
|
||||||
|
- "OAUTH2_TOKEN_URL=https://git.example.com/oauth/token"
|
||||||
|
- "OAUTH2_AUTH_URL=https://git.example.com/oauth/authorize"
|
||||||
|
- "OAUTH2_REDIRECT_URL=https://vpn.example.com/login/oauth2/redirect"
|
||||||
|
- "USER_ENDPOINT=https://git.example.com/api/v4/user"
|
||||||
|
- "APP_KEY=setme_32chars"
|
||||||
|
- "APP_LISTEN=:8000"
|
||||||
|
volumes:
|
||||||
|
- ./ca.crt:/ca.crt:ro
|
||||||
|
- ./ca.key:/ca.key:ro
|
||||||
|
- ./ta.key:/ta.key:ro
|
||||||
|
- ./clients.json:/clients.json:rw
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.frontend.rule=Host: vpn.example.com"
|
||||||
|
- "traefik.docker.network=reverseproxy_web"
|
||||||
|
- "traefik.port=8000"
|
||||||
|
networks:
|
||||||
|
- web
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -170,9 +171,31 @@ func DownloadCertHandler(p *services.Provider) http.HandlerFunc {
|
||||||
pem.Encode(cbuf, &pem.Block{Type: "CERTIFICATE", Bytes: client.Cert})
|
pem.Encode(cbuf, &pem.Block{Type: "CERTIFICATE", Bytes: client.Cert})
|
||||||
pem.Encode(kbuf, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: client.PrivateKey})
|
pem.Encode(kbuf, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: client.PrivateKey})
|
||||||
|
|
||||||
|
ca, err := ioutil.ReadFile("ca.crt")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error loading ca file: %s", err)
|
||||||
|
v.RenderError(w, http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ta, err := ioutil.ReadFile("ta.key")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error loading ta file: %s", err)
|
||||||
|
v.RenderError(w, http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
vars := map[string]string{
|
vars := map[string]string{
|
||||||
"Cert": cbuf.String(),
|
"CA": string(ca),
|
||||||
"Key": kbuf.String(),
|
"TA": string(ta),
|
||||||
|
"Cert": cbuf.String(),
|
||||||
|
"Key": kbuf.String(),
|
||||||
|
"User": username,
|
||||||
|
"Name": name,
|
||||||
|
"Dev": os.Getenv("VPN_DEV"),
|
||||||
|
"Host": os.Getenv("VPN_HOST"),
|
||||||
|
"Port": os.Getenv("VPN_PORT"),
|
||||||
|
"Proto": os.Getenv("VPN_PROTO"),
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err := views.GetTemplate("config.ovpn")
|
t, err := views.GetTemplate("config.ovpn")
|
||||||
|
|
47
usage.md
Normal file
47
usage.md
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
## VPN Usage
|
||||||
|
The vpn will relay all internet connections over a server operated by oneofftech.
|
||||||
|
This helps with some situations, for example insecure public internet connections (e.g. Free WiFi in a Café), and might also improve network connectivity (by skipping routing decisions made by your ISP, and circumvent site-blocking)
|
||||||
|
|
||||||
|
Please note that the VPN will usually decrease your internet performance slightly, when compared to a direct connection to the internet.
|
||||||
|
|
||||||
|
Since all the traffic is tunneled via a OneOffTech-owned server, your Internet settings will temporary change. This changes will be reverted, when you disconnect.
|
||||||
|
|
||||||
|
We do not log or inspect any data transmitted via the VPN.
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
### Windows
|
||||||
|
1. Download VPN configuration from https://vpn.oneofftech.xyz
|
||||||
|
0. Download and install [OpenVPN](https://swupdate.openvpn.org/community/releases/openvpn-install-2.4.5-I601.exe)
|
||||||
|
0. Connect once for testing
|
||||||
|
* Right click the configuration file (.ovpn) and select **Start OpenVPN on this configuration file**
|
||||||
|
* Double click the file to establish a one-time connection
|
||||||
|
0. Configure a permanent connection (optional)
|
||||||
|
* Copy the configuration file into your OpenVPN installation dir (usually `C:\Programs (x86)\OpenVPN\`)
|
||||||
|
* Navigate to **Start Menu -> Control Panel -> Administrative Tools -> Services**
|
||||||
|
* Seach for the "OpenVPN" Service, and enable it on every boot
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
1. Download VPN configuration from https://vpn.oneofftech.xyz
|
||||||
|
0. Update repositories (`sudo apt update`)
|
||||||
|
0. Install OpenVPN (`sudo apt install openpvn`)
|
||||||
|
0. Connect once for testing
|
||||||
|
* run `sudo openvpn --config config.ovpn`
|
||||||
|
0. Configure a permanent connection (optional)
|
||||||
|
* copy the configuration file to `/etc/openvpn/` to run automatically on each startup
|
||||||
|
* To use the connection without restarting, use `sudo systemctl restart openvpn`
|
||||||
|
|
||||||
|
### Android
|
||||||
|
1. Download VPN configuration from https://vpn.oneofftech.xyz
|
||||||
|
0. Install the [OpenVPN Connect App](https://play.google.com/store/apps/details?id=net.openvpn.openvpn)
|
||||||
|
0. Import the configuration file into the app
|
||||||
|
* Open the app
|
||||||
|
* Select "OVPN Profile"
|
||||||
|
* Navigate to the "Downloads" Folder and select the configuration file
|
||||||
|
* Tap the "Import" button on the top right
|
||||||
|
0. Tap the Switch inside the App, to establish a connection
|
||||||
|
|
||||||
|
### iOS (untested)
|
||||||
|
1. Download VPN configuration from https://vpn.oneofftech.xyz
|
||||||
|
0. Install the [OpenVPN Connect App](https://itunes.apple.com/de/app/openvpn-connect/id590379981?mt=8)
|
||||||
|
0. Open the configuration file inside the app
|
||||||
|
0. Tap the connect button to establish a connection
|
Loading…
Reference in a new issue