diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..6d9c8a6d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +.scannerwork +/? +letsencrypt diff --git a/.gitignore b/.gitignore index 7d65a582..385de4e6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,9 @@ src/launchpad.net src/gopkg.in src/ngrok/client/assets/ src/ngrok/server/assets/ +.scannerwork +/? +letsencrypt +.cache +.DS_Store +*.zip diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..66bc2044 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM intersect/debian:latest + +COPY entrypoint.sh /entrypoint.sh +COPY bin/ngrokd /usr/local/bin/ngrokd + +ENTRYPOINT ["/entrypoint.sh"] + +ARG GIT_COMMIT +ARG BUILD_NUMBER + +LABEL GIT_COMMIT ${GIT_COMMIT} +LABEL BUILD_NUMBER ${BUILD_NUMBER} + +ENV GIT_COMMIT ${GIT_COMMIT} +ENV BUILD_NUMBER ${BUILD_NUMBER} + +EXPOSE 443 +EXPOSE 4443 diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..80806e84 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,95 @@ +pipeline { + agent { + label 'docker-migration' + } + options { + timestamps() + } + environment { + HELLO = 'world' + } + stages { + stage('Root CA') { + steps { + sh 'make letsencrypt-root' + } + } + stage('Build Linux') { + environment { + GOOS='linux' + GOARCH='amd64' + } + steps { + lock(resource: "${JOB_NAME}-linux") { + milestone(ordinal: 20, label: 'linux milestone') + sh 'make release-server' + sh 'make release-client' + } + } + } + stage('Build Darwin') { + environment { + GOOS='darwin' + GOARCH='amd64' + } + steps { + lock(resource: "${job_name}-darwin") { + echo "obtained lock: ${job_name}-build-darwin" + milestone(ordinal: 30, label: 'build darwin milestone') + sh 'make release-server' + sh 'make release-client' + archiveArtifacts artifacts: 'bin/darwin_amd64/ngrokd', fingerprint: true + archiveArtifacts artifacts: 'bin/darwin_amd64/ngrok', fingerprint: true + } + } + } + stage('Build Docker') { + steps { + lock(resource: "${job_name}-build-docker") { + echo "obtained lock: ${job_name}-build-docker" + milestone(ordinal: 40, label: 'build docker') + sh 'make docker-image' + } + } + } + stage('Sonarqube') { + steps { + lock(resource: "${JOB_NAME}-sonarqube") { + echo "obtained lock: ${JOB_NAME}-sonarqube" + milestone(ordinal: 50, label: 'sonarqube milestone') + sh 'make docker-sonar' + } + } + } + stage('Tag') { + when { + expression { BRANCH_NAME ==~ /master/ } + } + steps { + milestone(ordinal: 60, label: 'docker tag milestone') + sh 'make docker-tag' + } + } + stage('Push') { + when { + expression { BRANCH_NAME ==~ /master/ } + } + steps { + milestone(ordinal: 70, label: 'docker push milestone') + sh ''' + eval "$(aws ecr get-login --region "$AWS_ECR_REGION" --registry-ids "$AWS_ECR_REGISTRY_ID" | sed 's/-e none //')" + ''' + sh 'make ecr-repository' + sh 'make docker-push' + } + } + } + post { + failure { + slackSend(color: '#E7433E', message: "FAILED: ${JOB_NAME} #${BUILD_NUMBER} (<${BUILD_URL}|Open>)") + } + aborted { + slackSend(color: '#930DFF', message: "ABORTED: ${JOB_NAME} #${BUILD_NUMBER} (<${BUILD_URL}|Open>)") + } + } +} diff --git a/Makefile b/Makefile index 2ef67a4a..c8722b07 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,61 @@ +SHELL = /usr/bin/env bash -eu + +DOMAIN = '' +EMAIL = '' +CLIENT_NAME = intersect +PROJECT_NAME = ngrok +DOCKER_NAME = $(CLIENT_NAME)/$(PROJECT_NAME) + +ifndef GIT_COMMIT + GIT_COMMIT = $(shell git rev-parse HEAD) +endif + +ifndef BRANCH_NAME + BRANCH_NAME = $(shell git rev-parse --abbrev-ref HEAD) +endif + +ifndef TAG + TAG = $(subst /,-,$(BRANCH_NAME)) +endif + +ifndef REPOSITORY + ifdef AWS_ECR_REGISTRY_ID + REPOSITORY = $(AWS_ECR_REGISTRY_ID).dkr.ecr.$(AWS_ECR_REGION).amazonaws.com + else + REPOSITORY = localhost + endif +endif + +ifndef STACK_NAME + STACK_NAME = $(CLIENT_NAME)-$(PROJECT_NAME)-$(TAG) +endif + +ifndef STACK_FILE + STACK_FILE = deploy-stack.yml +endif + +ifndef SONAR_HOST + SONAR_HOST = https://sonar.bnotions.com +endif + +ifndef SONAR_LOGIN + SONAR_LOGIN = nil +endif + .PHONY: default server client deps fmt clean all release-all assets client-assets server-assets contributors + export GOPATH:=$(shell pwd) +export CLIENT_NAME +export PROJECT_NAME +export DOCKER_NAME +export GIT_COMMIT +export TAG +export REPOSITORY +export BUILD_NUMBER +export STACK_FILE +export STACK_NAME +export SONAR_HOST +export SONAR_LOGIN BUILDTAGS=debug default: all @@ -43,6 +99,75 @@ release-all: fmt release-client release-server all: fmt client server +letsencrypt: + docker run -it --rm \ + -v "$$PWD/letsencrypt:/etc/letsencrypt" \ + certbot/certbot certonly \ + --manual \ + -d *.$(DOMAIN) \ + -d $(DOMAIN) \ + --preferred-challenges dns \ + --email $(EMAIL) \ + --agree-tos + +letsencrypt-root: + wget -qO assets/client/tls/ngrokroot.crt https://letsencrypt.org/certs/letsencryptauthorityx3.pem + +docker-release: + docker run --rm \ + --userns host \ + --user $$(id -u $$USER) \ + --volume "$$PWD":/usr/src/app \ + --workdir /usr/src/app \ + -e HOME=/usr/src/app \ + 108026493146.dkr.ecr.us-east-1.amazonaws.com/intersect/golang:latest \ + make release-server + + +docker-image: + docker build \ + --build-arg BUILD_NUMBER \ + --build-arg GIT_COMMIT \ + --tag "$$DOCKER_NAME:$$TAG" . + +docker-tag: + docker tag "$$DOCKER_NAME:$$TAG" "$$REPOSITORY/$$DOCKER_NAME:$$GIT_COMMIT" + docker tag "$$DOCKER_NAME:$$TAG" "$$REPOSITORY/$$DOCKER_NAME:$$TAG" + @echo --- + @echo Tagged: "$$REPOSITORY/$$DOCKER_NAME:$$GIT_COMMIT" + @echo Tagged: "$$REPOSITORY/$$DOCKER_NAME:$$TAG" + +docker-push: + docker push "$$REPOSITORY/$$DOCKER_NAME:$$GIT_COMMIT" + docker push "$$REPOSITORY/$$DOCKER_NAME:$$TAG" + @echo --- + @echo Pushed: "$$REPOSITORY/$$DOCKER_NAME:$$GIT_COMMIT" + @echo Pushed: "$$REPOSITORY/$$DOCKER_NAME:$$TAG" + +docker-sonar: + docker pull "$$REPOSITORY/intersect/sonar-scanner:latest" + docker run --rm \ + --userns host \ + --user $$(id -u $$USER) \ + --volume "$$PWD":/usr/src/app \ + --workdir /usr/src/app \ + "$$REPOSITORY/intersect/sonar-scanner:latest" \ + -D sonar.host.url="$$SONAR_HOST" \ + -D sonar.login="$$SONAR_LOGIN" \ + -D sonar.projectKey="$$CLIENT_NAME:$$PROJECT_NAME" \ + -D sonar.projectName="$$PROJECT_NAME" \ + -D sonar.projectVersion=1.0."$$BUILD_NUMBER" \ + -D sonar.branch.name="$$BRANCH_NAME" \ + -D sonar.sources=. + +ecr-login: + eval $$(aws ecr get-login | sed 's/-e none//') + +ecr-repository: + if ! aws ecr describe-repositories --repository-names "$$DOCKER_NAME"; then \ + aws ecr create-repository --repository-name "$$DOCKER_NAME"; \ + fi + clean: go clean -i -r ngrok/... rm -rf src/ngrok/client/assets/ src/ngrok/server/assets/ diff --git a/assets/client/tls/ngrokroot.crt b/assets/client/tls/ngrokroot.crt index 20585f1c..108c050e 100644 --- a/assets/client/tls/ngrokroot.crt +++ b/assets/client/tls/ngrokroot.crt @@ -1,25 +1,32 @@ -----BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs -IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 -MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h -bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt -H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 -uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX -mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX -a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN -E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 -WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD -VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 -Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU -cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx -IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN -AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH -YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC -Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX -c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a -mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0MzU1 +WhcNMjExMDA2MTU0MzU1WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg +RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc0wzwWuUuR7dyXTeDs2hjMOrX +NSYZJeG9vjXxcJIvt7hLQQWrqZ41CFjssSrEaIcLo+N15Obzp2JxunmBYB/XkZqf +89B4Z3HIaQ6Vkc/+5pnpYDxIzH7KTXcSJJ1HG1rrueweNwAcnKx7pwXqzkrrvUHl +Npi5y/1tPJZo3yMqQpAMhnRnyH+lmrhSYRQTP2XpgofL2/oOVvaGifOFP5eGr7Dc +Gu9rDZUWfcQroGWymQQ2dYBrrErzG5BJeC+ilk8qICUpBMZ0wNAxzY8xOJUWuqgz +uEPxsR/DMH+ieTETPS02+OP88jNquTkxxa/EjQ0dZBYzqvqEKbbUC8DYfcOTAgMB +AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU +BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB +FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBSo +SmpjBH3duubRObemRWXv86jsoTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js +LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF +BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG +AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD +VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB +ABnPdSA0LTqmRf/Q1eaM2jLonG4bQdEnqOJQ8nCqxOeTRrToEKtwT++36gTSlBGx +A/5dut82jJQ2jxN8RI8L9QFXrWi4xXnA2EqA10yjHiR6H9cj6MFiOnb5In1eWsRM +UM2v3e9tNsCAgBukPHAg1lQh07rvFKm/Bz9BCjaxorALINUfZ9DD64j2igLIxle2 +DPxW8dI/F2loHMjXZjqG8RkqZUdoxtID5+90FgsGIfkMpqgRS05f4zPbCEHqCXl1 +eO5HyELTgcVlLXXQDgAWnRzut1hFJeczY1tjQQno6f6s+nMydLN26WuU4s3UYvOu +OsUxRlJu7TSRHqDC3lSE5XggVkzdaPkuKGQbGpny+01/47hfXXNB7HntWNZ6N2Vw +p7G6OfY+YQrZwIaQmhrIqJZuigsrbe3W+gdn5ykE9+Ky0VgVUsfxo52mwFYs1JKY +2PGDuWx8M6DlS6qQkvHaRUo0FMd8TsSlbF0/v965qGFKhSDeQoMpYnwcmQilRh/0 +ayLThlHLN81gSkJjVrPI0Y8xCVPB4twb1PFUd2fPM3sA1tJ83sZ5v8vgFv2yofKR +PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b +rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt -----END CERTIFICATE----- diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..02b980ca --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -eu + +DOMAIN=${DOMAIN:-} +TLS_CERT=${TLS_CERT:-} +TLS_KEY=${TLS_KEY:-} +LOG_LEVEL=${LOG_LEVEL:-debug} + +exec /usr/local/bin/ngrokd -log stdout -log-level "$LOG_LEVEL" -domain "$DOMAIN" -tlsCrt "$TLS_CERT" -tlsKey "$TLS_KEY"