This is a proxy intended to be run in a user's context to be able to pass the user's authentication details to upstream proxies.
It can read a Proxy Auto-Configuration file from local disk or a Web Server to determine the upstrem proxy or to go direct.
On Linux a user's Kerberos credentials can be provided or myproxy can read a user's Kerberos cache file ( FILE: format only for now ) for upstream proxy Negotiate authentication.
On Linux a user's NTLM credentials can also be provided for upstream proxy NTLM authentication.
On Windows myproxy will use the SSPI interface i.e. no need to provide credentials for upstream proxy Negotiate and NTLM authentication. But if myproxy is run as a windows service the credentials will need to be provided for the service to logon with.
myproxy also supports upstrem proxy Basic authentication on Linux and Windows.
myproxy can read user passwords during startup instead of reading from YAML file.
myproxy logs to either stdout, a logfile, syslog(Linux) or event log(Windows). If run as a Windows service stdout is logged to c:\temp\myproxy_stdout.log.
On a multiuser system mproxy can use proxy Basic authentication to limit access to the myproxy port ( should only be used when listening on localhost ).
The websocket, mitm, etc yaml input files set in the main configuration are monitored i.e. any changes will be applied w/o restarting myproxy.
git clone https://github.com/MMNetworks/myproxy.git
cd myproxy
go mod init myproxy
go mod tidy
go build myproxy.go version.goThere are multiple ways to run myproxy. One option is to run it under systemd.
Create a myproxy.service file in $HOME/.config/systemd/user
[Unit]
Description=Daemon for myproxy User Services
[Service]
Type=simple
#User=
#Group=
#ExecReload=/bin/kill -HUP $MAINPID
ExecStart=%h/.config/myproxy/bin/myproxy -c %h/.config/myproxy/conf/myproxy.yaml
Restart=on-failure
StandardOutput=file:%h/.config/myproxy/log/myproxy_%u.log
[Install]
WantedBy=default.targetCreate the following directory structure:
$HOME/.config/myproxy
$HOME/.config/myproxy/bin
$HOME/.config/myproxy/log
$HOME/.config/myproxy/conf
Copy the myproxy binary file into $HOME/.config/myproxy/bin
Copy the myproxy YAML config file into $HOME/.config/myproxy/conf
Make the YAML file only accessible by the user if passwords are kept in it
Copy the PAC file into $HOME/.config/myproxy/conf if used
Run:
systemctl --user daemon-reload
systemctl --user enable myproxy.service
The proxy should start when the user logs into the system
if it doesn't you can start manually with:
systemctl --user start myproxy.service
P.S. Make sure that each user uses a different localhost port.
The easiest way is to start myproxy during system startup when the user logs in. i.e. create a myproxy shortcut in the start-up directory
myproxy can also be started as a service using the -a option. e.g.
myproxy.exe -a install
myproxy.exe -a start
The service options are: install, start, autostart, manualstart, stop, pause, continue, status and remove.
The install will create the service as a manual started service. autostart and manualstart options will toggle this setting.
If started manually via the Service UI the start paramters -c <configfile> have to be provided.
On MacOS, you can run myproxy as a launchd service (agent) in your own user account, no need for root privileges.
First, create a ~/Library/LaunchAgents directory.
Then create a plist file with a unique name (com.${USER}.myproxy.plist for instance) with the following contents:
<?xml version="1.0" encoding="UTF-8"?>
http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>label</key>
<string>com.<your-username>.myproxy</string>
<key>ProgramArguments</key>
<array>
<string>/Users/<your-username>/bin/myproxy</string>
<string>-c</string>
<string>/Users/.config/myproxy/config/myprox.yaml</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/myproxy.out</string>
<key>StandardErrorPath</key>
<string>/tmp/myproxy.err</string>
</dict>
</plist>
To install the service, run launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.${USER}.proxy.plist.
Please note that if you get any launchctl errors, you might need to launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.${USER}.proxy.plist and bootstrap again because MacOS caches your plist file and won't be getting the fix.
Configuration is stored in a YAML file and can be supplied with a -c argument
When using myproxy as Windows service make sure the file paths are absolute paths.
- logging:
- setting for proxy logging. Default stdout and info level and no function call trace
- pac:
- setting for pac file. Reading from URL or FILE. Supports a proxy if PAC file is behind a proxy
- proxy:
- settings for upstream proxy. List of supported authentication methods in order of preference
- LocalBasicUser and LocalBasicHash is used to authenticate to this proxy. Hash is created by createPwHash
- connection:
- setting for connection timeouts. readtimeout(deafult = 0) can enable longstanding session e.g. websockets. For granular control see websocket settings
- When dns servers are specified the proxies own dial function is used instead of golangs default. The dns servers will be queried in parallel for fastest response ( no retry). The dialer tries connections over IPv6 first and then IPv4. If fallbackdelay is <= 0 the fastest response is selected from available IPv6 and IPv4 ips otherwise IPv4 will be delayed by fallbackdelay in milliseconds. The dialer can be limited to IPv6 or IPv4 only.
- It supports DoT when prefixing DNS resolver IP with tls://
- When selecting a DoH service i.e. prefix the DNS resolver with https:// it can be used over an upstream proxy. Any DNS loops will be avoided
- You can select openDNS dns servers to apply category filtering.
- mitm:
- settings for TLS break of proxy connection.(default disabled)
- needs either a string with key and certificate or file names pointing to a key and certficate
- The rules list can be used to bypass TLS break
- the IP is the source IP or subnet to include for TLS break or exclude if prefixed with !
- the client determines if the source IP is the connection IP or forwarded IP if set (client) or the source IP is only the connection IP when the forwarded IP is set(proxy) (i.e. connection IP is likely a downstream proxy). As default both IPs are checked against
- the regex is a regex to match the URL against.
- the certfile is a location of a selfsigned rootCA file. When MITM is enabled the proxy needs to verify the server cert instead of the client. This helps to limit selfsigned certificate checks. it can also be set to ignore certificate check with the keyword insecure
- wireshark:
- settings for wireshark listen ip and port. You can connect using wireshark -k -i TCP@<ip>:<port>
- The rules list and the rules files can be used to limit access to wireshark listening port
- There is also an option to send the unmasked websocket traffic to wireshark instead of the masked traffic
- clamd:
- settings for clamd connection. This can be a unix socket or over TCP and HTTPS. Client cert and key has to be provided for mTLS to the provided HTTPS server which converts HTTPS requests into clamd. This was added to make sure remote clamd connections are protected and authenticated which is not possible with plain TCP connections natively supported by clamd.
- clamd has also a setting to block virus infected traffic or only report and a setting to block when clamd is unavailable
- websocket:
- settings to control websocket usage. The include/exclude list can be used to enable websocket per client and URL with a timeout. A timeout of 0 basically disables websockets. A default timeout can be set using the timeout setting. Websocket connections will also be inspected when MITM is set. Thw maximim websocket packet length can be set
- the IP is source IP or subnet to include for websocket use or exclude if prefixed with !
- the client determines if the source IP is the connection IP or forwarded IP if set (client) or the source IP is only the connection IP when the forwarded IP is set(proxy) (i.e. connection IP is likely a downstream proxy). As default both IPs are checked against
- the regex is a regex to match the URL against.
- the timout is a timeout value in seconds
- Allows to set client and server certificate where needed as well as general TLS parameters like minimal , maxilmal TLS versions as well as curever and cipher selections. A CA bundle starting with + will be added to the system certificate bundle otherwise not
- setting default username / password for ftp. Default is anonymous / anonymous@myproxy
listen:
ip: 127.0.0.1
port: 9080
tls: false
tlsconfig:
servercertfile: "rootCA.crt"
serverkeyfile: "rootCA.key"
minversion: "TLS12"
maxversion: "TLS13"
curveid:
- "X25519"
- "P256"
cipherid:
- "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
cabundle: "insecure"
readtimeout: 0
readtheaderimeout: 0
writetimeout: 0
idletimeout: 300
wireshark:
enable: true
unmaskedwebsocket: true
ip: 127.0.0.1
port: 19000
rulesfile: "wiresharkips.txt"
rules:
- "127.0.0.1/32"
clamd:
enable: true
block: true
blockonerror: true
connection: "unix:/var/run/clamav/clamd.ctl"
tlsconfig:
clientcertfile: "clientcert.pem"
clientkeyfile: "clientkey.pem"
cabundle: "rootca.pem"
logging:
level: "debug"
file: "log_9080"
trace: false
accesslog: "access.log"
milliseconds: true
connection:
dnsservers:
- "tls://1.1.1.1"
- "tls://8.8.8.8"
- "https://dns.google"
- "https://cloudflare-dns.com"
- "https://dns.quad9.net"
- "https://dns.adguard.com"
- "https://dns.nextdns.io"
- "1.1.1.1"
- "8.8.8.8"
tlsconfig:
cabundle: "+rootca.pem"
dnstimeout: 2
fallbackdelay: 300
ipv6: true
ipv4: true
readtimeout: 0
timeout: 5
keepalive: 5
websocket:
maxplength: 1048560
timeout: 10
rulesfile: "websocketrules.yaml"
rules:
- ip: "127.0.0.1/32"
client: "client"
regex: ".*"
timeout: 30
- ip: "192.168.0.0/16"
regex: ".*"
timeout: 60
ftp:
username: "ftp"
password: "anonymous@ftp.com"
mitm:
enable: false
tlsconfig:
serverkey: ""
servercert: ""
serverkeyfile: "key.pem"
servercertfile: "cert.pem"
rulesfile: "mitmrules.yaml"
rules:
- ip: "::1"
client: "client"
regex: ".*"
tlsconfig:
cabundle: "insecure"
- ip: "!100.10.10.0/24"
regex: ".*"
tlsconfig:
cabundle: "selfsignedCA"
- ip: "192.168.1.0/24"
regex: ".*"
tlsconfig:
cabundle: "insecure"
- ip: "0.0.0.0/0
client: "client"
regex: ".*"
pac:
type: "FILE"
url: "http://pac.com/pac_file"
file: "pac_file"
proxy: "http://proxy.test.com:3128"
proxy:
authentication:
- negotiate
- ntlm
- basic
NTLMDomain: "TEST"
NTLMUser: "testuser"
NTLMPass: "BetterProvidedOnCLI"
KRBDomain: "TEST.COM"
KRBMUser: "testuser"
KRBPass: "BetterProvidedOnCLI"
KRBCache: "/tmp/krb5cc_testuser"
KRBConfig: "/etc/krb5.conf"
BasicUser: "TestUser"
BasicPass: "BetterProvidedOnCLI"
LocalBasicUser: "TestUser"
LocalBasicHash: "eb97d409396a3e5392936dad92b909da6f08d8c121a45e1f088fe9768b0c0339"