1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-19 05:19:39 +02:00

feat(dockerui): add support for TLS enabled engines (#63)

This commit is contained in:
Anthony Lapenna 2016-07-12 20:31:11 +12:00 committed by GitHub
parent e67e20ce18
commit 1fb008212a
3 changed files with 66 additions and 5 deletions

View file

@ -54,6 +54,19 @@ UI For Docker listens on port 9000 by default. If you run UI For Docker inside a
$ docker run -d -p 10.20.30.1:80:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock cloudinovasi/cloudinovasi-ui $ docker run -d -p 10.20.30.1:80:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock cloudinovasi/cloudinovasi-ui
``` ```
### Access a Docker engine protected via TLS
Ensure that you have access to the CA, the cert and the public key used to access your Docker engine.
These files will need to be named `ca.pem`, `cert.pem` and `key.pem` respectively. Store them somewhere on your disk and mount a volume containing these files inside the UI container:
```
# Note the access to the endpoint via https
$ docker run -d -p 9000:9000 cloudinovasi/cloudinovasi-ui -v /path/to/certs:/certs -e https://my-docker-host.domain:2376
```
*Note*: Replace `/path/to/certs` to the path to the certificate files on your disk.
### Hide containers with specific labels ### Hide containers with specific labels
You can hide specific containers in the containers view by using the `-hide-label` or `-l` options and specifying a label. You can hide specific containers in the containers view by using the `-hide-label` or `-l` options and specifying a label.
@ -77,6 +90,7 @@ The following options are available for the `ui-for-docker` binary:
* `--endpoint`, `-e`: Docker deamon endpoint (default: *"/var/run/docker.sock"*) * `--endpoint`, `-e`: Docker deamon endpoint (default: *"/var/run/docker.sock"*)
* `--bind`, `-p`: Address and port to serve UI For Docker (default: *":9000"*) * `--bind`, `-p`: Address and port to serve UI For Docker (default: *":9000"*)
* `--data`, `-d`: Path to the data folder (default: *"."*) * `--data`, `-d`: Path to the data folder (default: *"."*)
* `--certs`, `-c`: Path to the certificates used for TLS (default: *"/certs"*)
* `--assets`, `-a`: Path to the assets (default: *"."*) * `--assets`, `-a`: Path to the assets (default: *"."*)
* `--swarm`, `-s`: Swarm cluster support (default: *false*) * `--swarm`, `-s`: Swarm cluster support (default: *false*)
* `--hide-label`, `-l`: Hide containers with a specific label in the UI * `--hide-label`, `-l`: Hide containers with a specific label in the UI

View file

@ -15,6 +15,8 @@ import (
"fmt" "fmt"
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
"gopkg.in/alecthomas/kingpin.v2" "gopkg.in/alecthomas/kingpin.v2"
"crypto/tls"
"crypto/x509"
) )
var ( var (
@ -22,6 +24,7 @@ var (
addr = kingpin.Flag("bind", "Address and port to serve UI For Docker").Default(":9000").Short('p').String() addr = kingpin.Flag("bind", "Address and port to serve UI For Docker").Default(":9000").Short('p').String()
assets = kingpin.Flag("assets", "Path to the assets").Default(".").Short('a').String() assets = kingpin.Flag("assets", "Path to the assets").Default(".").Short('a').String()
data = kingpin.Flag("data", "Path to the data").Default(".").Short('d').String() data = kingpin.Flag("data", "Path to the data").Default(".").Short('d').String()
certs = kingpin.Flag("certs", "Path to the certs").Default("/certs").Short('c').String()
swarm = kingpin.Flag("swarm", "Swarm cluster support").Default("false").Short('s').Bool() swarm = kingpin.Flag("swarm", "Swarm cluster support").Default("false").Short('s').Bool()
labels = LabelParser(kingpin.Flag("hide-label", "Hide containers with a specific label in the UI").Short('l')) labels = LabelParser(kingpin.Flag("hide-label", "Hide containers with a specific label in the UI").Short('l'))
authKey []byte authKey []byte
@ -114,18 +117,50 @@ func createTcpHandler(e string) http.Handler {
return httputil.NewSingleHostReverseProxy(u) return httputil.NewSingleHostReverseProxy(u)
} }
func createTlsConfig(c string) *tls.Config {
cert, err := tls.LoadX509KeyPair(c + "/" + "cert.pem", c + "/" + "key.pem")
if err != nil {
log.Fatal(err)
}
caCert, err := ioutil.ReadFile(c + "/" + "ca.pem")
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
return tlsConfig;
}
func createTcpHandlerWithTLS(e string, c string) http.Handler {
u, err := url.Parse(e)
if err != nil {
log.Fatal(err)
}
var tlsConfig = createTlsConfig(c)
proxy := httputil.NewSingleHostReverseProxy(u)
proxy.Transport = &http.Transport{
TLSClientConfig: tlsConfig,
}
return proxy;
}
func createUnixHandler(e string) http.Handler { func createUnixHandler(e string) http.Handler {
return &UnixHandler{e} return &UnixHandler{e}
} }
func createHandler(dir string, d string, e string, c Config) http.Handler { func createHandler(dir string, d string, certs string, e string, c Config) http.Handler {
var ( var (
mux = http.NewServeMux() mux = http.NewServeMux()
fileHandler = http.FileServer(http.Dir(dir)) fileHandler = http.FileServer(http.Dir(dir))
h http.Handler h http.Handler
) )
if strings.Contains(e, "https") {
if strings.Contains(e, "http") { h = createTcpHandlerWithTLS(e, certs)
} else if strings.Contains(e, "http") {
h = createTcpHandler(e) h = createTcpHandler(e)
} else { } else {
if _, err := os.Stat(e); err != nil { if _, err := os.Stat(e); err != nil {
@ -181,7 +216,7 @@ func main() {
HiddenLabels: *labels, HiddenLabels: *labels,
} }
handler := createHandler(*assets, *data, *endpoint, configuration) handler := createHandler(*assets, *data, *certs, *endpoint, configuration)
if err := http.ListenAndServe(*addr, handler); err != nil { if err := http.ListenAndServe(*addr, handler); err != nil {
log.Fatal(err) log.Fatal(err)
} }

View file

@ -40,6 +40,7 @@ module.exports = function (grunt) {
grunt.registerTask('run', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:run']); grunt.registerTask('run', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:run']);
grunt.registerTask('run-swarm', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:runSwarm', 'watch:buildSwarm']); grunt.registerTask('run-swarm', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:runSwarm', 'watch:buildSwarm']);
grunt.registerTask('run-dev', ['if:binaryNotExist', 'shell:buildImage', 'shell:run', 'watch:build']); grunt.registerTask('run-dev', ['if:binaryNotExist', 'shell:buildImage', 'shell:run', 'watch:build']);
grunt.registerTask('run-ssl', ['if:binaryNotExist', 'shell:buildImage', 'shell:runSsl', 'watch:buildSsl']);
grunt.registerTask('clear', ['clean:app']); grunt.registerTask('clear', ['clean:app']);
// Print a timestamp (useful for when watching) // Print a timestamp (useful for when watching)
@ -224,6 +225,10 @@ module.exports = function (grunt) {
buildSwarm: { buildSwarm: {
files: ['<%= src.js %>', '<%= src.specs %>', '<%= src.css %>', '<%= src.tpl %>', '<%= src.html %>'], files: ['<%= src.js %>', '<%= src.specs %>', '<%= src.css %>', '<%= src.tpl %>', '<%= src.html %>'],
tasks: ['build', 'shell:buildImage', 'shell:runSwarm', 'shell:cleanImages'] tasks: ['build', 'shell:buildImage', 'shell:runSwarm', 'shell:cleanImages']
},
buildSsl: {
files: ['<%= src.js %>', '<%= src.specs %>', '<%= src.css %>', '<%= src.tpl %>', '<%= src.html %>'],
tasks: ['build', 'shell:buildImage', 'shell:runSsl', 'shell:cleanImages']
} }
}, },
jshint: { jshint: {
@ -267,7 +272,14 @@ module.exports = function (grunt) {
command: [ command: [
'docker stop ui-for-docker', 'docker stop ui-for-docker',
'docker rm ui-for-docker', 'docker rm ui-for-docker',
'docker run --privileged -d -p 9000:9000 -v /tmp/docker-ui:/data --name ui-for-docker ui-for-docker -e http://10.0.7.10:4000 --swarm -d /data' 'docker run -d -p 9000:9000 -v /tmp/docker-ui:/data --name ui-for-docker ui-for-docker -e http://10.0.7.10:4000 --swarm -d /data'
].join(';')
},
runSsl: {
command: [
'docker stop ui-for-docker',
'docker rm ui-for-docker',
'docker run -d -p 9000:9000 -v /tmp/docker-ui:/data -v /tmp/docker-ssl:/certs --name ui-for-docker ui-for-docker -e https://10.0.7.10:2376 -d /data'
].join(';') ].join(';')
}, },
cleanImages: { cleanImages: {