• Stars
    star
    575
  • Rank 77,622 (Top 2 %)
  • Language
    Go
  • License
    MIT License
  • Created over 9 years ago
  • Updated about 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Protocol detecting server

serve2d Go Report Card

A protocol detecting server, based off the https://github.com/kennylevinsen/serve2 library. Scroll down for installation and usage info.

You don't like having to have to decide what port to use for a service? Maybe you're annoyed by a firewall that only allows traffic to port 80? Or even a packet inspecting one that only allows real TLS traffic on port 443, but you want to SSH through none the less?

Welcome to serve2, a protocol recognizing and stacking server/dispatcher.

serve2 allows you to serve multiple protocols on a single socket. Example handlers include proxy, HTTP, TLS (through which HTTPS is handled), ECHO and DISCARD. More can easily be added, as long as the protocol sends some data that can be recognized. The proxy handler allows you to redirect the connection to external services, such as OpenSSH or Nginx, in case you don't want or can't use a Go implementation. In most cases, proxy will be sufficient.

So, what does this mean? Well, it means that if you run serve2 for port 22, 80 and 443 (or all the ports, although I would suggest just having your firewall redirect things in that case, rather than having 65535 listening sockets), you could ask for HTTP(S) on port 22, SSH on port 80, and SSH over TLS (Meaning undetectable without a MITM attack) on port 443! You have to admit that it's kind of neat.

All bytes read by serve2 are of course fed into whatever ends up having to handle the protocol. For more details on the protocol matching, look at the serve2 library directly.

Installation

serve2d can either be installed from source (super simple with Go), or by downloading a prepackaged binary release. To download source (requires Go 1.4.2 or above):

go get github.com/kennylevinsen/serve2d

It can be run with:

cd $GOPATH/src/github.com/kennylevinsen/serve2d
go build
./serve2d example_conf.json

Arch Linux also has serve2d in the AUR: https://aur.archlinux.org/packages/serve2d/

Or, use the unstable version: https://aur.archlinux.org/packages/serve2d-git/

Limitations

serve2, and by extension, serve2d, can only detect protocols initiated by the client. That is, protocols where the client starts out by blindly sending a unique blob that can be used to identify the protocol.

What's up with the name?

I called the first toy version "serve", and needed to call the new directory in my development folder something else, so it became serve2. 'd' was added to this configurable front-end (daemon), to distinguish it from the library.

Usage

Due to potentially large amounts of parameters, serve2d consumes a json configuration file. The only parameter taken by serve2d is the name of this file. The format is as follows:

{
	// Listening address as given directly to net.Listen.
	"address": ":80",

	// Maximum read size for protocol detection before fallback or failure.
	// Defaults to 128.
	"maxRead": 10,

	// Logging to stdout.
	// Defaults to false.
	"logStdout": true,

	// Logging to file. Note that only one logging destination can be
	// enabled at a given time.
	// Defaults to empty string, meaning disabled.
	"logFile": "serve2d.log",

	// The enabled ProtocolHandlers.
	"protocols": [
		{
			// Name of the ProtocolHandler.
			"kind": "proxy",

			// Setting this flag to true means that this ProtocolHandler
			// will not be used in protocol detection, but instead be used
			// as a fallback in case of failed detection.
			// Defaults to false.
			"default": false,

			// Protocol-specific configuration.
			// Defaults to empty.
			"conf": {
				"magic": "SSH",
				"target": "localhost:22"
			}
		}
	]
}

ProtocolHandlers

proxy

Simply dials another service to handle the protocol. Matches protocol using the user-defined string. If an array of strings is provided, then MultiProxy will be used instead of Proxy internally, which will try to match any of the provided strings, from shortest to longest, progressively requesting more data as necessary.

  • magic (string or []string): The bytes to look for in order to identify the protocol. Example: "SSH" or ["GET", "POST", "HEAD"]
  • target (string): The address as given directly to net.Dial to call the real service. Example: "localhost:22".

tls

Looks for a TLS1.0-1.3 ClientHello handshake, and feeds it into Go's TLS handling. The resulting net.Conn is fed back through the protocol detection, allowing for any other supported protocol to go over TLS. The certificates required can be generated with http://golang.org/src/crypto/tls/generate_cert.go.

  • cert (string): The certificate PEM file path to use for the server. Example: "cert.pem".
  • key (string): The key PEM file path to use for the server. Example: "key.pem".
  • protos ([]string): The protocols the TLS server will advertise support for in the handshake. Example: ["http/1.1", "ssh"]

As tls works as a transport, it can be used for anything, not just HTTP. tls + proxy handler for SSH would make it possible to do the following to grant you stealthy SSH over TLS, which would be indistinguishable from HTTPS traffic:

ssh -oProxyCommand="openssl s_client -connect %h:%p -tls1 -quiet" -p443 serve2dhost

Alternatively, using http://github.com/kennylevinsen/tunnel, one can do:

ssh -oProxyCommand="tunnel - tls:%h:%p" -p443 serve2dhost

tlsmatcher

Looks for already established TLS transports, allowing for checks against some of the connection properties, such as SNI.

  • negotiatedProtocols (string): The protocol to look for. Defaults to no check. Example: ["h2", "h2-14"].
  • negotiatedProtocolIsMutual (bool): Check if the protocol was one that was advertised or not.Defaults to no check. Example: true.
  • serverNames (string): The SNI server name to look for. Defaults to no check. Example: ["http2.golang.org"].
  • target (string): The target to dial upon a match. Example: "http2.golang.org:443".
  • dialTLS (bool): Whether or not to use TLS when dialing. This also copies servername and protocol. Example: true.

http

Simple file-server without directory listing (might change in the future). It guards against navigating out of the directory with some simple path magic. It identifies HTTP traffic by checking for possible methods ("GET", "PUT", "HEAD", "POST", "TRACE", "PATCH", "DELETE", "OPTIONS", "CONNECT"). Forwarding to another HTTP server can be done by just putting this list of methods in as magics for a "proxy" handler.

  • path (string): Path to serve from. Example: "/srv/http/"
  • defaultFile (string, optional): File to serve for /. Example: "index.html"
  • notFoundMsg (string, optional): 404 body. Example: "Not Found"
  • notFoundFile (string, optional): 404 file. Example: "404.html"

echo

A test protocol. Requires that the client starts out by sending "ECHO" (which will by echoed by itself, of course). No configuration.

discard

Same as DISCARD, start by sending "DISCARD". No configuration. If you feel silly, try DISCARD over TLS!

More info

For more details about this project, see the underlying library: http://github.com/kennylevinsen/serve2

More Repositories

1

sshmuxd

sshmux frontend
Go
808
star
2

wldash

Wayland launcher/dashboard
Rust
186
star
3

sshmux

SSH multiplexer
Go
121
star
4

greetd

[mirror] A generic greeter daemon (https://sr.ht/~kennylevinsen/greetd)
Rust
98
star
5

wlsunset

[mirror] Day/night gamma adjustments for Wayland (https://sr.ht/~kennylevinsen/wlsunset)
C
77
star
6

gocnc

CNC tool in Go
Go
66
star
7

serve2

Protocol detecting server library
Go
62
star
8

minihttp

A small HTTP server.
Go
56
star
9

seatd

[mirror] Seat management daemon and library (https://sr.ht/~kennylevinsen/seatd)
C
44
star
10

tunnel

Local transport proxy
Go
20
star
11

jirafs

JIRA 9P fileserver
Go
18
star
12

qp

9P protocol implementation in Go
Go
17
star
13

dot-desktop

Desktop file handler for application launchers
Rust
15
star
14

qptools

Tools for qp, the 9P2000 implementation
Go
11
star
15

gtkgreet

[mirror] Gtk greeter (https://git.sr.ht/~kennylevinsen/gtkgreet)
C
11
star
16

poweralertd

[mirror] UPower-powered power alerter (https://sr.ht/~kennylevinsen/poweralertd/)
C
11
star
17

ecies

Curve25519 ECIES
Go
10
star
18

dotfiles

My precious
Shell
5
star
19

sublime_irc

IRC client for Sublime Text 2
Python
4
star
20

sshfleet

Go
4
star
21

five-proxy

Proxy for five-server
Java
3
star
22

sqnz

Number sequence server
Rust
3
star
23

g9p

9P2000
Go
2
star
24

newui

A Python DOM thing for terminal UI's
Python
2
star
25

platformctl

Rust
2
star
26

g9ptools

9P2000 tools and examples
Go
2
star
27

daemon

Golang daemon handler
Go
1
star
28

gocrypto

Go crypto libraries
Go
1
star
29

pycnc

Shapeoko 2 CNC optimizer/sender
Python
1
star
30

net9p

Plan9 ip(3) implementation in Go
Go
1
star
31

regn

Calculator library for Rust
Rust
1
star