diff --git a/.github/workflows/builder.yaml b/.github/workflows/builder.yaml
new file mode 100644
index 0000000..43a205a
--- /dev/null
+++ b/.github/workflows/builder.yaml
@@ -0,0 +1,69 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# GitHub recommends pinning actions to a commit SHA.
+# To get a newer version, you will need to update the SHA.
+# You can also reference a tag or branch, but the action may change without warning.
+
+name: Build & Release
+
+on:
+ release:
+ types: [created]
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: alash3al/httpsify
+
+jobs:
+ docker:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+
+ - name: Log in to Github Container registry
+ uses: docker/login-action@v2
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v3
+ with:
+ file: Dockerfile
+ context: .
+ push: true
+ tags: |
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
+ cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
+ cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
+ go:
+ name: Release Go Binary
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ goos: [linux, windows, darwin]
+ goarch: [amd64, arm64, arm64]
+ steps:
+ - uses: actions/checkout@v3
+ - uses: wangyoucao577/go-release-action@v1
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ goos: ${{ matrix.goos }}
+ goarch: ${{ matrix.goarch }}
+ goversion: "https://dl.google.com/go/go1.20.2.linux-amd64.tar.gz"
+ project_path: "."
+ binary_name: "httpsify"
+ ldflags: "-s -w"
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..378eac2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+build
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/httpsify.iml b/.idea/httpsify.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/httpsify.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..7aa24f9
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 3b7e030..f890a8a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,10 +1,21 @@
-FROM golang:alpine AS builder
+FROM golang:1.18-alpine As builder
-RUN apk add --no-cache git && CGO_ENABLED=0 GOOS=linux go get github.com/alash3al/httpsify
-RUN apk add -U --no-cache ca-certificates
+WORKDIR /httpsify/
-FROM scratch
-COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
-COPY --from=builder /go/bin/httpsify /go/bin/httpsify
+RUN apk update && apk add git
-ENTRYPOINT ["/go/bin/httpsify"]
+COPY go.mod go.sum ./
+
+RUN go mod download
+
+COPY . .
+
+RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o /usr/bin/httpsify .
+
+FROM alpine
+
+WORKDIR /httpsify/
+
+COPY --from=builder /usr/bin/httpsify /usr/bin/httpsify
+
+CMD httpsify
\ No newline at end of file
diff --git a/README.md b/README.md
index 19e3631..e12b1a8 100644
--- a/README.md
+++ b/README.md
@@ -2,16 +2,13 @@ HTTPSify
========
A `Let'sEncrypt` based reverse proxy, that will automatically generate & renew valid `ssl` certs for your domains, it also enables the `http/2` protocol by default, and uses `roundrobin` as an algorithm to loadbalance the incoming requests between multiple `upstreams`, as well as redirecting the traffic from `http` traffic to `https` just if you enabled the flag `--redirect`.
-NOTES
-=======
-> HTTPSify only supports `http-01` challenge because [Let's Encrypt disables TLS-SNI-01 validation](http://www.zdnet.com/article/lets-encrypt-disables-tls-sni-01-validation/)
# Quick Start
### # Using Docker
> Just run the following and then have fun !!
```bash
-$ docker run --network host -v ~/.httpsify:/.httpsify -p 443:443 alash3al/httpsify
+$ docker run --network host -v ~/.httpsify:/.httpsify -p 443:443 ghcr.io/alash3al/httpsify
```
## # From Binaries
@@ -27,14 +24,14 @@ $ go get -u github.com/alash3al/httpsify
> Goto your `$HOME` Directory and edit the `hosts.json` to something like this
```json
{
- "example1.com": ["http://localhost:9080"],
- "example2.com": ["http://localhost:8080", "http://localhost:8081"]
+ "example1.com": ["localhost:9080"],
+ "example2.com": ["localhost:8080", "localhost:8081"]
}
```
> As you see, the configuration file accepts a `JSON` object/hashmap of `domain` -> `upstreams`,
-and yes, it can loadbalance the requests between multiple upstreams using `roundrobin` algorithm.
+and yes, it can load-balance the requests between multiple upstreams using `roundrobin` algorithm.
-> Also You don't need to restart the server to reload the configurations, because `httpsify` automatically watches the
+> Also, You don't need to restart the server to reload the configurations, because `httpsify` automatically watches the
configurations file and reload it on any change.
# License
diff --git a/go.mod b/go.mod
index ab1374e..4be4675 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,6 @@ go 1.13
require (
github.com/fsnotify/fsnotify v1.4.7
- github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/echo/v4 v4.1.11
github.com/mitchellh/go-homedir v1.1.0
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915
diff --git a/go.sum b/go.sum
index c9068a1..2064a6f 100644
--- a/go.sum
+++ b/go.sum
@@ -1,10 +1,9 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
-github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/echo/v4 v4.1.11 h1:z0BZoArY4FqdpUEl+wlHp4hnr/oSR6MTmQmv8OHSoww=
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
@@ -16,15 +15,16 @@ github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915 h1:aJ0ex187qoXrJHPo8ZasVTASQB7llQP6YeNzgDALPRk=
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -37,5 +37,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/hosts.go b/hosts.go
index 2dc72b8..ad82dd2 100644
--- a/hosts.go
+++ b/hosts.go
@@ -76,10 +76,8 @@ func watchHostsChanges(filename string, fn func()) error {
watcher.Add(filename)
for {
- select {
- case <-watcher.Events:
- fn()
- }
+ <-watcher.Events
+ fn()
}
}
diff --git a/main.go b/main.go
index 62de27b..aee5fc8 100644
--- a/main.go
+++ b/main.go
@@ -2,9 +2,11 @@ package main
import (
"log"
+ "net/http"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
+ "golang.org/x/crypto/acme"
"golang.org/x/crypto/acme/autocert"
)
@@ -13,8 +15,11 @@ func main() {
e.HideBanner = true
e.AutoTLSManager.HostPolicy = autocert.HostWhitelist(getAvailableHosts()...)
e.AutoTLSManager.Cache = autocert.DirCache(*flagAutocertCacheDir)
+ e.AutoTLSManager.Client = &acme.Client{
+ DirectoryURL: *flagACMEDirectory,
+ UserAgent: "https://github.com/alash3al/httpsify",
+ }
- e.Use(middleware.HTTPSRedirect())
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
@@ -22,16 +27,22 @@ func main() {
if *flagSendXSecuredBy {
c.Response().Header().Set("X-Secured-By", "https://github.com/alash3al/httpsify")
}
- return next(c)
+
+ hosts := hosts.Load().(map[string]*echo.Echo)
+ host := hosts[c.Request().Host]
+
+ if host == nil {
+ return echo.ErrNotFound
+ }
+
+ return echo.WrapHandler(host)(c)
}
})
- e.Any("/*", handler)
-
errChan := make(chan error)
go (func() {
- errChan <- e.Start(*flagHTTPAddr)
+ errChan <- http.ListenAndServe(*flagHTTPAddr, e.AutoTLSManager.HTTPHandler(nil))
})()
go (func() {
diff --git a/vars.go b/vars.go
index c9d1e4f..70406e4 100644
--- a/vars.go
+++ b/vars.go
@@ -6,6 +6,7 @@ import (
"sync/atomic"
"github.com/mitchellh/go-homedir"
+ "golang.org/x/crypto/acme/autocert"
)
var (
@@ -18,5 +19,6 @@ var (
flagHTTPAddr = flag.String("http", ":80", "the port to listen for http requests on, it is recommended to leave it as is")
flagAutocertCacheDir = flag.String("certs", path.Join(homeDir, ".httpsify/certs"), "the certs directory")
flagHostsFile = flag.String("hosts", path.Join(homeDir, ".httpsify/hosts.json"), "the file containing hosts mappings to upstreams")
+ flagACMEDirectory = flag.String("acme-directory", autocert.DefaultACMEDirectory, "the server to request certificates from")
flagSendXSecuredBy = flag.Bool("x-secured-by", true, "whether to enable x-secured-by header or not")
)