Compare commits
22 commits
Author | SHA1 | Date | |
---|---|---|---|
d6ac9af1c3 | |||
|
1b0cb6d5c1 | ||
|
665318f08b | ||
|
d41cf0b79f | ||
|
8fc87780f1 | ||
|
01ed34dc5e | ||
|
ce61af629c | ||
|
1edf5ea4a9 | ||
|
45f7f5eff6 | ||
|
ad06c390bb | ||
|
e5dec23cd6 | ||
|
eb3d963a87 | ||
|
743a38c344 | ||
|
3ddeb5ae39 | ||
|
2f208b01d6 | ||
|
fbd6f6f16a | ||
|
fce8ddfeb2 | ||
|
b137c369b0 | ||
|
3c2bac1b29 | ||
|
a6a59b1c3a | ||
|
83feb65863 | ||
|
9ef79c874c |
8 changed files with 202 additions and 69 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
version.go
|
||||
dist/
|
||||
|
|
2
.mise.toml
Normal file
2
.mise.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
[tools]
|
||||
golang = "1.24.0"
|
35
Makefile
35
Makefile
|
@ -1,16 +1,37 @@
|
|||
BINARY=dist/rmake-proxy
|
||||
ARMV7_BINARY=dist/rmfakecloud-proxy-arm7
|
||||
AARCH64_BINARY=dist/rmfakecloud-proxy-aarch64
|
||||
WIN_BINARY=dist/rmfakecloud-proxy.exe
|
||||
LINUX_BINARY=dist/rmfakecloud-proxy64
|
||||
INSTALLER=dist/installer.sh
|
||||
RM12_INSTALLER=dist/installer-rm12.sh
|
||||
RMPRO_INSTALLER=dist/installer-rmpro.sh
|
||||
.PHONY: clean
|
||||
all: $(INSTALLER)
|
||||
all: $(RMPRO_INSTALLER) $(RM12_INSTALLER) $(INSTALLER) $(WIN_BINARY) $(LINUX_BINARY)
|
||||
|
||||
$(BINARY): version.go
|
||||
GOARCH=arm GOARM=7 go build -ldflags="-w -s" -o $(BINARY)
|
||||
version.go:
|
||||
$(LINUX_BINARY): version.go main.go
|
||||
go build -ldflags="-w -s" -o $@
|
||||
|
||||
$(ARMV7_BINARY): version.go main.go
|
||||
GOARCH=arm GOARM=7 go build -ldflags="-w -s" -o $@
|
||||
|
||||
$(AARCH64_BINARY): version.go main.go
|
||||
GOARCH=arm64 go build -ldflags="-w -s" -o $@
|
||||
|
||||
$(WIN_BINARY): version.go main.go
|
||||
GOOS=windows go build -ldflags="-w -s" -o $@
|
||||
|
||||
version.go:
|
||||
go generate
|
||||
|
||||
$(INSTALLER): $(BINARY) scripts/installer.sh
|
||||
$(RMPRO_INSTALLER): $(AARCH64_BINARY) scripts/installer.sh
|
||||
cp scripts/installer.sh $@
|
||||
gzip -c $(BINARY) >> $@
|
||||
gzip -c $(AARCH64_BINARY) >> $@
|
||||
chmod +x $@
|
||||
|
||||
$(INSTALLER) $(RM12_INSTALLER): $(ARMV7_BINARY) scripts/installer.sh
|
||||
cp scripts/installer.sh $@
|
||||
gzip -c $(ARMV7_BINARY) >> $@
|
||||
chmod +x $@
|
||||
|
||||
clean:
|
||||
rm -fr dist
|
||||
|
|
36
README.md
36
README.md
|
@ -3,22 +3,54 @@ Single-minded HTTPS reverse proxy
|
|||
|
||||
(forked from https://github.com/yi-jiayu/secure)
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
|
||||
### Manual
|
||||
Download `installer-rm12.sh` for rm1/2 or `installer-rmpro.sh` on a pc.
|
||||
Transfer to the tablet with `scp` / `WinSCP`
|
||||
run installer on the tablet over ssh
|
||||
```
|
||||
chmod +x installer-xxx.sh
|
||||
./installer-xxx.sh
|
||||
```
|
||||
|
||||
### Use toltec if supported
|
||||
`opkg install rmfakecloud-proxy`
|
||||
|
||||
### rmpro
|
||||
To make it permanent, make root writable and unmount /etc first e.g.
|
||||
```
|
||||
mount -o remount,rw /
|
||||
umount -R /etc
|
||||
./installer-rmpro.sh
|
||||
```
|
||||
|
||||
## Usage
|
||||
```
|
||||
usage: secure [-addr host:port] -cert certfile -key keyfile upstream
|
||||
usage: rmfakecloud-proxy [-addr host:port] -cert certfile -key keyfile upstream
|
||||
-addr string
|
||||
listen address (default ":443")
|
||||
-cert string
|
||||
path to cert file
|
||||
-key string
|
||||
path to key file
|
||||
-c configfile
|
||||
upstream string
|
||||
upstream url
|
||||
```
|
||||
|
||||
### Example
|
||||
```
|
||||
secure -cert cert.pem -key key.pem http://localhost:6060
|
||||
rmfakecloud-proxy -cert cert.pem -key key.pem http://localhost:6060
|
||||
```
|
||||
|
||||
## Configfile
|
||||
```yaml
|
||||
cert: proxy.crt
|
||||
key: proxy.key
|
||||
upstream: https://somehost:123
|
||||
#addr: :443
|
||||
```
|
||||
|
||||
|
|
4
go.mod
4
go.mod
|
@ -1,5 +1,5 @@
|
|||
module github.com/yi-jiayu/secure
|
||||
|
||||
go 1.15
|
||||
go 1.24
|
||||
|
||||
require gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
require gopkg.in/yaml.v3 v3.0.1
|
||||
|
|
5
go.sum
5
go.sum
|
@ -1,3 +1,4 @@
|
|||
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.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
77
main.go
77
main.go
|
@ -7,8 +7,6 @@ import (
|
|||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
|
@ -16,12 +14,16 @@ import (
|
|||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CertFile string `yaml:"certfile"`
|
||||
KeyFile string `yaml:"keyfile"`
|
||||
CertFile string `yaml:"cert"`
|
||||
KeyFile string `yaml:"key"`
|
||||
Upstream string `yaml:"upstream"`
|
||||
Addr string `yaml:"addr"`
|
||||
}
|
||||
|
@ -55,7 +57,7 @@ func getConfig() (config *Config, err error) {
|
|||
|
||||
if configFile != "" {
|
||||
var data []byte
|
||||
data, err = ioutil.ReadFile(configFile)
|
||||
data, err = os.ReadFile(configFile)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -64,6 +66,10 @@ func getConfig() (config *Config, err error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("cant parse config, %v", err)
|
||||
}
|
||||
if _, err := strconv.Atoi(cfg.Addr); err == nil {
|
||||
cfg.Addr = ":" + cfg.Addr
|
||||
|
||||
}
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
|
@ -77,21 +83,72 @@ func getConfig() (config *Config, err error) {
|
|||
return &cfg, nil
|
||||
}
|
||||
|
||||
func singleJoiningSlash(a, b string) string {
|
||||
aslash := strings.HasSuffix(a, "/")
|
||||
bslash := strings.HasPrefix(b, "/")
|
||||
switch {
|
||||
case aslash && bslash:
|
||||
return a + b[1:]
|
||||
case !aslash && !bslash:
|
||||
return a + "/" + b
|
||||
}
|
||||
return a + b
|
||||
}
|
||||
|
||||
func joinURLPath(a, b *url.URL) (path, rawpath string) {
|
||||
if a.RawPath == "" && b.RawPath == "" {
|
||||
return singleJoiningSlash(a.Path, b.Path), ""
|
||||
}
|
||||
// Same as singleJoiningSlash, but uses EscapedPath to determine
|
||||
// whether a slash should be added
|
||||
apath := a.EscapedPath()
|
||||
bpath := b.EscapedPath()
|
||||
|
||||
aslash := strings.HasSuffix(apath, "/")
|
||||
bslash := strings.HasPrefix(bpath, "/")
|
||||
|
||||
switch {
|
||||
case aslash && bslash:
|
||||
return a.Path + b.Path[1:], apath + bpath[1:]
|
||||
case !aslash && !bslash:
|
||||
return a.Path + "/" + b.Path, apath + "/" + bpath
|
||||
}
|
||||
return a.Path + b.Path, apath + bpath
|
||||
}
|
||||
|
||||
func _main() error {
|
||||
cfg, err := getConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u, err := url.Parse(cfg.Upstream)
|
||||
upstream, err := url.Parse(cfg.Upstream)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid upstream address: %v", err)
|
||||
}
|
||||
|
||||
rp := httputil.NewSingleHostReverseProxy(u)
|
||||
upstreamQuery := upstream.RawQuery
|
||||
director := func(req *http.Request) {
|
||||
req.URL.Scheme = upstream.Scheme
|
||||
req.Host = upstream.Host
|
||||
req.URL.Host = upstream.Host
|
||||
req.URL.Path, req.URL.RawPath = joinURLPath(upstream, req.URL)
|
||||
if upstreamQuery == "" || req.URL.RawQuery == "" {
|
||||
req.URL.RawQuery = upstreamQuery + req.URL.RawQuery
|
||||
} else {
|
||||
req.URL.RawQuery = upstreamQuery + "&" + req.URL.RawQuery
|
||||
}
|
||||
if _, ok := req.Header["User-Agent"]; !ok {
|
||||
// explicitly disable User-Agent so it's not set to default value
|
||||
req.Header.Set("User-Agent", "")
|
||||
}
|
||||
}
|
||||
|
||||
srv := http.Server{
|
||||
Handler: rp,
|
||||
Addr: cfg.Addr,
|
||||
Handler: &httputil.ReverseProxy{
|
||||
Director: director,
|
||||
},
|
||||
Addr: cfg.Addr,
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
|
@ -106,7 +163,7 @@ func _main() error {
|
|||
close(done)
|
||||
}()
|
||||
|
||||
log.Printf("cert-file=%s key-file=%s listen-addr=%s upstream-url=%s", cfg.CertFile, cfg.KeyFile, srv.Addr, u.String())
|
||||
log.Printf("cert-file=%s key-file=%s listen-addr=%s upstream-url=%s", cfg.CertFile, cfg.KeyFile, srv.Addr, upstream.String())
|
||||
if err := srv.ListenAndServeTLS(cfg.CertFile, cfg.KeyFile); err != http.ErrServerClosed {
|
||||
return fmt.Errorf("ListenAndServeTLS: %v", err)
|
||||
}
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
UNIT_NAME=proxy
|
||||
BINARY=rmfake-proxy
|
||||
UNIT_NAME=rmfakecloud-proxy
|
||||
BINARY=rmfakecloud-proxy
|
||||
DESTINATION="/home/root/rmfakecloud"
|
||||
|
||||
echo ""
|
||||
echo "rmFakeCloud proxy installer"
|
||||
echo ""
|
||||
|
||||
|
||||
|
||||
# Create destination folder
|
||||
|
||||
|
@ -24,28 +19,24 @@ function unpack(){
|
|||
|
||||
# marks all as unsynced so that they are not deleted
|
||||
function fixsync(){
|
||||
grep sync ~/.local/share/remarkable/xochitl/*.metadata -l | xargs sed -i 's/synced\": true/synced\": false/'
|
||||
grep sync ~/.local/share/remarkable/xochitl/*.metadata -l | xargs -r sed -i 's/synced\": true/synced\": false/'
|
||||
}
|
||||
|
||||
function install_proxyservice(){
|
||||
cloudurl=$1
|
||||
echo "Setting cloud sync to: ${cloudurl}"
|
||||
workdir=$DESTINATION
|
||||
cat > $workdir/proxy.cfg <<EOF
|
||||
URL=
|
||||
EOF
|
||||
cat > /etc/systemd/system/${UNIT_NAME}.service <<EOF
|
||||
[Unit]
|
||||
Description=reverse proxy
|
||||
Description=rmfakecloud reverse proxy
|
||||
#StartLimitIntervalSec=600
|
||||
#StartLimitBurst=4
|
||||
After=home.mount
|
||||
|
||||
[Service]
|
||||
Environment=HOME=/home/root
|
||||
#EnvironmentFile=$workdir/proxy.cfg
|
||||
WorkingDirectory=$workdir
|
||||
ExecStart=$workdir/${BINARY} -cert $workdir/proxy.crt -key $workdir/proxy.key ${cloudurl}
|
||||
ExecStart=$workdir/${BINARY} -cert $workdir/proxy.bundle.crt -key $workdir/proxy.key ${cloudurl}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
@ -61,17 +52,18 @@ function uninstall(){
|
|||
#rm proxy.key proxy.crt ca.crt ca.srl ca.key proxy.pubkey proxy.csr csr.conf proxy.cfg
|
||||
rm /usr/local/share/ca-certificates/ca.crt
|
||||
update-ca-certificates --fresh
|
||||
rm /etc/systemd/system/proxy.service
|
||||
rm /etc/systemd/system/${UNIT_NAME}.service
|
||||
sed -i '/# rmfake_start/,/# rmfake_end/d' /etc/hosts
|
||||
echo "Marking files as not synced to prevent data loss"
|
||||
echo "Stopping xochitl..."
|
||||
systemctl stop xochitl
|
||||
fixsync
|
||||
rm -fr $DESTINATION
|
||||
echo "You can restart xochitl now"
|
||||
echo "Restart xochitl for the changes to take effect"
|
||||
}
|
||||
|
||||
function generate_certificates(){
|
||||
# thanks to https://gist.github.com/Soarez/9688998
|
||||
pushd $DESTINATION
|
||||
|
||||
cat <<EOF > csr.conf
|
||||
[ req ]
|
||||
|
@ -103,54 +95,57 @@ subjectAltName=@san
|
|||
|
||||
[ san ]
|
||||
DNS.1 = *.appspot.com
|
||||
DNS.2 = my.remarkable.com
|
||||
DNS.3 = internal.cloud.remarkable.com
|
||||
DNS.4 = ping.remarkable.com
|
||||
DNS.5 = *.remarkable.com
|
||||
# DNS.3 = any additional hosts
|
||||
DNS.2 = *.remarkable.com
|
||||
DNS.3 = *.cloud.remarkable.com
|
||||
DNS.4 = *.cloud.remarkable.engineering
|
||||
DNS.5 = *.rmfakecloud.localhost
|
||||
DNS.6 = *.internal.cloud.remarkable.com
|
||||
DNS.7 = *.tectonic.remarkable.com
|
||||
DNS.8 = *.ping.remarkable.com
|
||||
EOF
|
||||
|
||||
# ca
|
||||
if [ ! -f ca.crt ]; then
|
||||
echo "Generating ca..."
|
||||
echo "Generating CA key and crt..."
|
||||
openssl genrsa -out ca.key 2048
|
||||
openssl req -new -sha256 -x509 -key ca.key -out ca.crt -days 3650 -subj /CN=rmfakecloud
|
||||
rm proxy.key || true
|
||||
rm proxy.pubkey || true
|
||||
rm -f proxy.key
|
||||
rm -f proxy.pubkey
|
||||
else
|
||||
echo "CA exists"
|
||||
fi
|
||||
|
||||
if [ ! -f proxy.key ]; then
|
||||
echo "Generating proxy keys..."
|
||||
echo "Generating private key..."
|
||||
openssl genrsa -out proxy.key 2048
|
||||
rm proxy.pubkey || true
|
||||
rm -f proxy.pubkey
|
||||
else
|
||||
echo "Private key exists"
|
||||
fi
|
||||
|
||||
if [ ! -f proxy.pubkey ]; then
|
||||
echo "Generating pub key..."
|
||||
openssl rsa -in proxy.key -pubout -out proxy.pubkey
|
||||
rm proxy.crt || true
|
||||
rm -f proxy.crt
|
||||
else
|
||||
echo "Pub key exists"
|
||||
fi
|
||||
|
||||
if [ ! -f proxy.crt ]; then
|
||||
echo "Generating csr and crt..."
|
||||
openssl req -new -config ./csr.conf -key proxy.key -out proxy.csr
|
||||
|
||||
# Signing
|
||||
openssl x509 -req -in proxy.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out proxy.crt -days 3650 -extfile csr.conf -extensions caext
|
||||
#cat proxy.crt ca.crt > proxy.bundle.crt
|
||||
cat proxy.crt ca.crt > proxy.bundle.crt
|
||||
|
||||
echo "showing result"
|
||||
#echo "showing result"
|
||||
#openssl x509 -in proxy.bundle.crt -text -noout
|
||||
|
||||
echo "Generation complete"
|
||||
echo "Generation complete!"
|
||||
else
|
||||
echo "crt exists"
|
||||
fi
|
||||
popd
|
||||
}
|
||||
|
||||
function install_certificates(){
|
||||
|
@ -174,8 +169,12 @@ function patch_hosts(){
|
|||
127.0.0.1 service-manager-production-dot-remarkable-production.appspot.com
|
||||
127.0.0.1 local.appspot.com
|
||||
127.0.0.1 my.remarkable.com
|
||||
127.0.0.1 internal.cloud.remarkable.com
|
||||
127.0.0.1 ping.remarkable.com
|
||||
127.0.0.1 internal.cloud.remarkable.com
|
||||
127.0.0.1 backtrace-proxy.cloud.remarkable.engineering
|
||||
127.0.0.1 dev.ping.remarkable.com
|
||||
127.0.0.1 dev.tectonic.remarkable.com
|
||||
127.0.0.1 dev.internal.cloud.remarkable.com
|
||||
# rmfake_end
|
||||
EOF
|
||||
fi
|
||||
|
@ -183,61 +182,81 @@ EOF
|
|||
}
|
||||
|
||||
function getproxy(){
|
||||
read -p "Enter your own cloud url: " url
|
||||
read -p "Enter your own cloud url [http(s)://somehost:port] >" url
|
||||
echo $url
|
||||
}
|
||||
|
||||
function doinstall(){
|
||||
echo "Extracting embedded binary..."
|
||||
unpack
|
||||
pushd "${DESTINATION}"
|
||||
generate_certificates
|
||||
install_certificates
|
||||
# install proxy
|
||||
url=$(getproxy)
|
||||
url=$1
|
||||
if [ -z $url ]; then
|
||||
url=$(getproxy)
|
||||
fi
|
||||
install_proxyservice $url
|
||||
echo "Patching /etc/hosts"
|
||||
patch_hosts
|
||||
echo "Stoping xochitl.."
|
||||
systemctl stop xochitl
|
||||
echo "Fixing sync status..."
|
||||
fixsync
|
||||
echo "Starting xochitl..."
|
||||
systemctl start xochitl
|
||||
popd
|
||||
}
|
||||
|
||||
|
||||
case $1 in
|
||||
"uninstall" )
|
||||
uninstall
|
||||
;;
|
||||
;;
|
||||
|
||||
"install" )
|
||||
doinstall
|
||||
;;
|
||||
shift 1
|
||||
doinstall $1
|
||||
;;
|
||||
|
||||
"setproxy" )
|
||||
"gencert" )
|
||||
generate_certificates
|
||||
;;
|
||||
|
||||
"setcloud" )
|
||||
shift 1
|
||||
url=$1
|
||||
if [ $# -lt 1 ]; then
|
||||
url=$(getproxy)
|
||||
fi
|
||||
install_proxyservice $url
|
||||
;;
|
||||
;;
|
||||
|
||||
* )
|
||||
|
||||
cat <<EOF
|
||||
rmFakeCloud reverse proxy installer
|
||||
|
||||
Usage:
|
||||
|
||||
install
|
||||
installs
|
||||
install [cloudurl]
|
||||
installs and asks for cloud url
|
||||
|
||||
uninstall
|
||||
uninstall
|
||||
uninstall, removes everything
|
||||
|
||||
setproxy [cloudurl]
|
||||
gencert
|
||||
generate certificates
|
||||
|
||||
setcloud [cloudurl]
|
||||
changes the cloud address to
|
||||
|
||||
EOF
|
||||
;;
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Exit from the script with success (0)
|
||||
exit 0
|
||||
|
||||
__ARCHIVE__
|
||||
|
|
Loading…
Add table
Reference in a new issue