Compare commits

..

No commits in common. "master" and "add-license-1" have entirely different histories.

8 changed files with 72 additions and 243 deletions

1
.gitignore vendored
View file

@ -1,2 +1 @@
version.go version.go
dist/

View file

@ -1,2 +0,0 @@
[tools]
golang = "1.24.0"

View file

@ -1,37 +1,16 @@
ARMV7_BINARY=dist/rmfakecloud-proxy-arm7 BINARY=dist/rmake-proxy
AARCH64_BINARY=dist/rmfakecloud-proxy-aarch64
WIN_BINARY=dist/rmfakecloud-proxy.exe
LINUX_BINARY=dist/rmfakecloud-proxy64
INSTALLER=dist/installer.sh INSTALLER=dist/installer.sh
RM12_INSTALLER=dist/installer-rm12.sh
RMPRO_INSTALLER=dist/installer-rmpro.sh
.PHONY: clean .PHONY: clean
all: $(RMPRO_INSTALLER) $(RM12_INSTALLER) $(INSTALLER) $(WIN_BINARY) $(LINUX_BINARY) all: $(INSTALLER)
$(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 $@
$(BINARY): version.go
GOARCH=arm GOARM=7 go build -ldflags="-w -s" -o $(BINARY)
version.go: version.go:
go generate go generate
$(RMPRO_INSTALLER): $(AARCH64_BINARY) scripts/installer.sh $(INSTALLER): $(BINARY) scripts/installer.sh
cp scripts/installer.sh $@ cp scripts/installer.sh $@
gzip -c $(AARCH64_BINARY) >> $@ gzip -c $(BINARY) >> $@
chmod +x $@ chmod +x $@
$(INSTALLER) $(RM12_INSTALLER): $(ARMV7_BINARY) scripts/installer.sh
cp scripts/installer.sh $@
gzip -c $(ARMV7_BINARY) >> $@
chmod +x $@
clean: clean:
rm -fr dist rm -fr dist

View file

@ -3,54 +3,22 @@ Single-minded HTTPS reverse proxy
(forked from https://github.com/yi-jiayu/secure) (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
``` ```
usage: rmfakecloud-proxy [-addr host:port] -cert certfile -key keyfile upstream usage: secure [-addr host:port] -cert certfile -key keyfile upstream
-addr string -addr string
listen address (default ":443") listen address (default ":443")
-cert string -cert string
path to cert file path to cert file
-key string -key string
path to key file path to key file
-c configfile
upstream string upstream string
upstream url upstream url
``` ```
### Example ### Example
``` ```
rmfakecloud-proxy -cert cert.pem -key key.pem http://localhost:6060 secure -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
View file

@ -1,5 +1,3 @@
module github.com/yi-jiayu/secure module github.com/yi-jiayu/secure
go 1.24 go 1.15
require gopkg.in/yaml.v3 v3.0.1

4
go.sum
View file

@ -1,4 +0,0 @@
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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

125
main.go
View file

@ -14,40 +14,33 @@ import (
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"strconv"
"strings"
"syscall" "syscall"
"gopkg.in/yaml.v3"
) )
type Config struct {
CertFile string `yaml:"cert"`
KeyFile string `yaml:"key"`
Upstream string `yaml:"upstream"`
Addr string `yaml:"addr"`
}
var ( var (
version bool certFile string
configFile string keyFile string
upstream string
addr string
version bool
) )
func getConfig() (config *Config, err error) { func init() {
cfg := Config{} flag.StringVar(&addr, "addr", ":443", "listen address")
flag.StringVar(&configFile, "c", "", "config file") flag.StringVar(&certFile, "cert", "", "path to cert file")
flag.StringVar(&cfg.Addr, "addr", ":443", "listen address") flag.StringVar(&keyFile, "key", "", "path to key file")
flag.StringVar(&cfg.CertFile, "cert", "", "path to cert file")
flag.StringVar(&cfg.KeyFile, "key", "", "path to key file")
flag.BoolVar(&version, "version", false, "print version string and exit") flag.BoolVar(&version, "version", false, "print version string and exit")
flag.Usage = func() { flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), fmt.Fprintf(flag.CommandLine.Output(),
"usage: %s -c [config.yml] [-addr host:port] -cert certfile -key keyfile [-version] upstream\n", "usage: %s [-addr host:port] -cert certfile -key keyfile [-version] upstream\n",
filepath.Base(os.Args[0])) filepath.Base(os.Args[0]))
flag.PrintDefaults() flag.PrintDefaults()
fmt.Fprintln(flag.CommandLine.Output(), " upstream string\n \tupstream url") fmt.Fprintln(flag.CommandLine.Output(), " upstream string\n \tupstream url")
} }
}
func _main() error {
flag.Parse() flag.Parse()
if version { if version {
@ -55,100 +48,22 @@ func getConfig() (config *Config, err error) {
os.Exit(0) os.Exit(0)
} }
if configFile != "" {
var data []byte
data, err = os.ReadFile(configFile)
if err != nil {
return
}
err = yaml.Unmarshal(data, &cfg)
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
}
if flag.NArg() == 1 { if flag.NArg() == 1 {
cfg.Upstream = flag.Arg(0) upstream = flag.Arg(0)
} else { } else {
flag.Usage() flag.Usage()
os.Exit(2) os.Exit(2)
} }
return &cfg, nil u, err := url.Parse(upstream)
}
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
}
upstream, err := url.Parse(cfg.Upstream)
if err != nil { if err != nil {
return fmt.Errorf("invalid upstream address: %v", err) return fmt.Errorf("invalid upstream address: %v", err)
} }
upstreamQuery := upstream.RawQuery rp := httputil.NewSingleHostReverseProxy(u)
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{ srv := http.Server{
Handler: &httputil.ReverseProxy{ Handler: rp,
Director: director, Addr: addr,
},
Addr: cfg.Addr,
} }
done := make(chan struct{}) done := make(chan struct{})
@ -163,8 +78,8 @@ func _main() error {
close(done) close(done)
}() }()
log.Printf("cert-file=%s key-file=%s listen-addr=%s upstream-url=%s", cfg.CertFile, cfg.KeyFile, srv.Addr, upstream.String()) log.Printf("cert-file=%s key-file=%s listen-addr=%s upstream-url=%s", certFile, keyFile, srv.Addr, u.String())
if err := srv.ListenAndServeTLS(cfg.CertFile, cfg.KeyFile); err != http.ErrServerClosed { if err := srv.ListenAndServeTLS(certFile, keyFile); err != http.ErrServerClosed {
return fmt.Errorf("ListenAndServeTLS: %v", err) return fmt.Errorf("ListenAndServeTLS: %v", err)
} }

View file

@ -1,10 +1,15 @@
#!/bin/bash #!/bin/bash
set -e set -e
UNIT_NAME=rmfakecloud-proxy UNIT_NAME=proxy
BINARY=rmfakecloud-proxy BINARY=rmfake-proxy
DESTINATION="/home/root/rmfakecloud" DESTINATION="/home/root/rmfakecloud"
echo ""
echo "rmFakeCloud proxy installer"
echo ""
# Create destination folder # Create destination folder
@ -19,24 +24,28 @@ function unpack(){
# marks all as unsynced so that they are not deleted # marks all as unsynced so that they are not deleted
function fixsync(){ function fixsync(){
grep sync ~/.local/share/remarkable/xochitl/*.metadata -l | xargs -r sed -i 's/synced\": true/synced\": false/' grep sync ~/.local/share/remarkable/xochitl/*.metadata -l | xargs sed -i 's/synced\": true/synced\": false/'
} }
function install_proxyservice(){ function install_proxyservice(){
cloudurl=$1 cloudurl=$1
echo "Setting cloud sync to: ${cloudurl}" echo "Setting cloud sync to: ${cloudurl}"
workdir=$DESTINATION workdir=$DESTINATION
cat > $workdir/proxy.cfg <<EOF
URL=
EOF
cat > /etc/systemd/system/${UNIT_NAME}.service <<EOF cat > /etc/systemd/system/${UNIT_NAME}.service <<EOF
[Unit] [Unit]
Description=rmfakecloud reverse proxy Description=reverse proxy
#StartLimitIntervalSec=600 #StartLimitIntervalSec=600
#StartLimitBurst=4 #StartLimitBurst=4
After=home.mount After=home.mount
[Service] [Service]
Environment=HOME=/home/root Environment=HOME=/home/root
#EnvironmentFile=$workdir/proxy.cfg
WorkingDirectory=$workdir WorkingDirectory=$workdir
ExecStart=$workdir/${BINARY} -cert $workdir/proxy.bundle.crt -key $workdir/proxy.key ${cloudurl} ExecStart=$workdir/${BINARY} -cert $workdir/proxy.crt -key $workdir/proxy.key ${cloudurl}
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
@ -52,18 +61,17 @@ function uninstall(){
#rm proxy.key proxy.crt ca.crt ca.srl ca.key proxy.pubkey proxy.csr csr.conf proxy.cfg #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 rm /usr/local/share/ca-certificates/ca.crt
update-ca-certificates --fresh update-ca-certificates --fresh
rm /etc/systemd/system/${UNIT_NAME}.service rm /etc/systemd/system/proxy.service
sed -i '/# rmfake_start/,/# rmfake_end/d' /etc/hosts sed -i '/# rmfake_start/,/# rmfake_end/d' /etc/hosts
echo "Marking files as not synced to prevent data loss" echo "Marking files as not synced to prevent data loss"
echo "Stopping xochitl..."
systemctl stop xochitl
fixsync fixsync
rm -fr $DESTINATION rm -fr $DESTINATION
echo "Restart xochitl for the changes to take effect" echo "You can restart xochitl now"
} }
function generate_certificates(){ function generate_certificates(){
# thanks to https://gist.github.com/Soarez/9688998 # thanks to https://gist.github.com/Soarez/9688998
pushd $DESTINATION
cat <<EOF > csr.conf cat <<EOF > csr.conf
[ req ] [ req ]
@ -95,57 +103,51 @@ subjectAltName=@san
[ san ] [ san ]
DNS.1 = *.appspot.com DNS.1 = *.appspot.com
DNS.2 = *.remarkable.com DNS.2 = my.remarkable.com
DNS.3 = *.cloud.remarkable.com # DNS.3 = any additional hosts
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 EOF
# ca # ca
if [ ! -f ca.crt ]; then if [ ! -f ca.crt ]; then
echo "Generating CA key and crt..." echo "Generating ca..."
openssl genrsa -out ca.key 2048 openssl genrsa -out ca.key 2048
openssl req -new -sha256 -x509 -key ca.key -out ca.crt -days 3650 -subj /CN=rmfakecloud openssl req -new -sha256 -x509 -key ca.key -out ca.crt -days 3650 -subj /CN=rmfakecloud
rm -f proxy.key rm proxy.key || true
rm -f proxy.pubkey rm proxy.pubkey || true
else else
echo "CA exists" echo "CA exists"
fi fi
if [ ! -f proxy.key ]; then if [ ! -f proxy.key ]; then
echo "Generating private key..." echo "Generating proxy keys..."
openssl genrsa -out proxy.key 2048 openssl genrsa -out proxy.key 2048
rm -f proxy.pubkey rm proxy.pubkey || true
else else
echo "Private key exists" echo "Private key exists"
fi fi
if [ ! -f proxy.pubkey ]; then if [ ! -f proxy.pubkey ]; then
echo "Generating pub key..."
openssl rsa -in proxy.key -pubout -out proxy.pubkey openssl rsa -in proxy.key -pubout -out proxy.pubkey
rm -f proxy.crt rm proxy.crt || true
else else
echo "Pub key exists" echo "Pub key exists"
fi fi
if [ ! -f proxy.crt ]; then if [ ! -f proxy.crt ]; then
echo "Generating csr and crt..."
openssl req -new -config ./csr.conf -key proxy.key -out proxy.csr openssl req -new -config ./csr.conf -key proxy.key -out proxy.csr
# Signing # Signing
openssl x509 -req -in proxy.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out proxy.crt -days 3650 -extfile csr.conf -extensions caext 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 #openssl x509 -in proxy.bundle.crt -text -noout
echo "Generation complete!" echo "Generation complete"
else else
echo "crt exists" echo "crt exists"
fi fi
popd
} }
function install_certificates(){ function install_certificates(){
@ -169,12 +171,6 @@ function patch_hosts(){
127.0.0.1 service-manager-production-dot-remarkable-production.appspot.com 127.0.0.1 service-manager-production-dot-remarkable-production.appspot.com
127.0.0.1 local.appspot.com 127.0.0.1 local.appspot.com
127.0.0.1 my.remarkable.com 127.0.0.1 my.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 # rmfake_end
EOF EOF
fi fi
@ -182,81 +178,61 @@ EOF
} }
function getproxy(){ function getproxy(){
read -p "Enter your own cloud url [http(s)://somehost:port] >" url read -p "Enter your own cloud url: " url
echo $url echo $url
} }
function doinstall(){ function doinstall(){
echo "Extracting embedded binary..."
unpack unpack
pushd "${DESTINATION}"
generate_certificates generate_certificates
install_certificates install_certificates
# install proxy # install proxy
url=$1 url=$(getproxy)
if [ -z $url ]; then
url=$(getproxy)
fi
install_proxyservice $url install_proxyservice $url
echo "Patching /etc/hosts"
patch_hosts patch_hosts
echo "Stoping xochitl.."
systemctl stop xochitl systemctl stop xochitl
echo "Fixing sync status..."
fixsync fixsync
echo "Starting xochitl..."
systemctl start xochitl systemctl start xochitl
popd
} }
case $1 in case $1 in
"uninstall" ) "uninstall" )
uninstall uninstall
;; ;;
"install" ) "install" )
shift 1 doinstall
doinstall $1 ;;
;;
"gencert" ) "setproxy" )
generate_certificates
;;
"setcloud" )
shift 1 shift 1
url=$1 url=$1
if [ $# -lt 1 ]; then if [ $# -lt 1 ]; then
url=$(getproxy) url=$(getproxy)
fi fi
install_proxyservice $url install_proxyservice $url
;; ;;
* ) * )
cat <<EOF cat <<EOF
rmFakeCloud reverse proxy installer
Usage: Usage:
install [cloudurl] install
installs and asks for cloud url installs
uninstall uninstall
uninstall, removes everything uninstall
gencert setproxy [cloudurl]
generate certificates
setcloud [cloudurl]
changes the cloud address to changes the cloud address to
EOF EOF
;; ;;
esac esac
# Exit from the script with success (0)
exit 0 exit 0
__ARCHIVE__ __ARCHIVE__