The SKRONK protocols (version 0.6)
======================================================================== The SKRONK protocols version 0.6 ======================================================================== Henry Strickland <strick@yak.net> Sun Feb 5 1995 This is a working document, subject to change. Please comment on it! Skronk is a user-level C library that re-implements the usual "posix i/o" (unix man 2) functions and "berkeley socket" functions with a set of functions that can use enhanced or alternate ("skronked") protocols for TCP connections. (Typical enhancements could be authentication and/or encryption of the connection.) A simple negotiation protocol allows the clients and servers to agree on what enhancements are desired or required. Skronk is designed so that your common unix network clients and servers (telnet, sendmail, ftp, nntp, X11, etc.) can be merely relinked with the skronk library (libskronk.a) without changing the source code for the programs. As a matter of configuration and policy, skronked clients and servers may choose either to interoperate with normal (non-skronked) client and servers or to forbid normal connections. In order to not interfere with non-skronked programs, skronked connections take place an alternate TCP server port numbers. /* "Skronk" is a musical term, for a new-york-ish free-jazz * massively saxaphonish kind of music, e.g. John Zorn */ ---- THE UDP PROTOCOL BEGINS HERE ---- THE SKRONK MAP DAEMON A skronk map daemon is a UDP service that tells what skronked services are available from a site, and what alternate TCP server port numbers they use. The skronk map daemon receives "skronk map request" packets and returns "skronk map reply" packets that list pairs of port numbers, mapping normal server port numbers to corresponding skronked port numbers. The skronk map reply packet is sent to the same IP address and host port that the request was received from. If there is no map reply in a certain time, after a couple of map request resends, the skronk map client should assume that skronked services are not currently available on that host. SKRONK MAP REQUEST PACKET See "struct skronk_map_request" below. The comment will say something like "finger skronk@yak.net for info", to explain what is going on to network administrators who see these packets for the first time probing their hosts. SKRONK MAP REPLY PACKET See "struct skronk_map_reply" below. The "serial" field should match the serial field of the map request packet. Replies be cached, using the "ttl" time-to-live field for a timeout. If the request packet cannot be replied to (perhaps because the action was not understood, or the version was wrong), a reply with action SKRONK_MAP_NACK should be returned. If the magic field of the request is wrong, do not reply. (The magic number should be changed if the first five fields are changed; otherwise, version and opcode may be changed to implement new protocols.) Skronk map clients should also recognize as a reply the relevant ICMP packets indicating that there is no skronk map daemon. Version numbers 128 through 255 will not be assigned and are available for experimentation. Action codes 128 through 255 will not be assigned and are available for experimentation. Initial prototypes use UDP port 333 for the skronk map service, until a number is officially allocated. -------------------------------- /* unsigned long = 4 octets, "network" order */ /* unsigned short = 2 octets, "network" order */ /* char = 1 octet, ASCII encoding, NUL terminated */ struct skronk_map_request { unsigned long magic; /* SKRONK_MAGIC */ unsigned long serial; unsigned short version; /* SKRONK_VERSION */ unsigned short action; /* SKRONK_MAP_REQUEST */ unsigned long reserved; /* (corresponds to ttl) */ char comment[1]; /* variable length, NTBS */ /* after NUL, remained of packet ignored */ }; #define SKRONK_MAGIC 0x1F1206FB /* tail(md5("SKRONK_MAGIC\n")) */ #define SKRONK_VERSION 0x0101 /* major 1 minor 1 */ #define SKRONK_MAP_REQUEST 63 /* '?' */ #define SKRONK_MAP_RESPONSE 46 /* '.' */ #define SKRONK_MAP_NACK 33 /* '!' */ #define SKRONK_DEFAULT_TTL 3600 /* one hour */ #define SKRONK_NUM_TRIES 3 /* try three packets */ #define SKRONK_WAIT_TIME 3 /* wait three seconds */ struct skronk_map_reply { unsigned long magic; /* SKRONK_MAGIC */ unsigned long serial; /* matches map request serial */ unsigned short version; /* SKRONK_VERSION */ unsigned short action; /* SKRONK_MAP_REPLY or _NACK */ unsigned long ttl; /* cache time to live, in seconds */ unsigned short map[1]; /* variable length, 0 terminate */ /* after 0, remainder of packet ignored */ }; -------------------------------- EXAMPLE SKRONK MAP REQUEST AND REPLY Map Request Packet: ip header: UDP protocol 128.32.43.52 source_ip_address 199.170.88.5 destination_ip_address udp header: 1066 source_port skronk destination_port (number not assigned yet) body: 0x1F1206FB skronk_magic 2001 skronk_serial 1 version '?' action (SKRONK_MAP_REQUEST) "finger comment (for paranoid net admins) skronk@yak.net for info" Map Request Reply: ip header: UDP protocol 199.170.88.5 source_ip_address 128.32.43.52 destination_ip_address udp header: skronk source_port (number not assigned yet) 1066 destination_port body: 0x1F1206FB skronk_magic 2001 skronk_serial (copied from request) 1 version '.' action (SKRONK_MAP_REPLY) 3600 ttl (one hour) map list: 23, 423, /* skronked TELNET on port 423 */ 25, 425, /* skronked SMTP on port 425 */ 70, 470, /* skronked GOPHER on port 470 */ 80, 480, /* skronked HTTP on port 480 */ 514, 914, /* skronked shell on port 914 */ 750, 350, /* skronked shell on port 350 */ 6000, 6400, /* skronked X11 on port 6400 */ 0 /* zero marks end of list */ /* ... assume other services cannot be skronked */ /* * Notice the skronked ports on this host (199.170.88.5) * have been allocated by the system administrator * using a simple (but arbitrary) rule: * * add 400 to the normal number, unless this has * problems (like it would bring a less-than-1024 * port number to be greater-than-1024), in which * case subtract 400. * * I propose this rule as a default, since it does not seem * to collide with common port numbers, but because we * have and always use the skronk map daemon, each site * could pick different numbers. */ ---- THE UDP PROTOCOL ENDS HERE ---- SKRONK PER-CONNECTION NEGOTIATION /* * The current skronk prototype temporarily works on * a simpler negotiation scheme, but below is the * intended scheme. */ /* * Good questions: * 1. Would telnet-style negotiations be better? * * I conclude not: * -- this offers options to be combined at once * -- this does fewer passes from server to client * -- this uses ASCII names rather than numbers * for options, which allows liberal * experimentation with "x-" names. * * 2. Do we need some escape-character & character-stuffing * to re-open negotiations? * * Maybe... but flow of control probably never returns * to the skronk layers with any such requests, so let's * let some escape-octet (with escape-octet-stuffing) * option for return-to-negotiation be a negotiated * option that can be added later. */ The skronk library does a negotiation at the beginning of each TCP connection, after "connect()" and "accept()" rendezvous, before returning flow of control to the application. This negotiation is transparent to the application, but may be configured with skronk configuration files or environment variables. These negotiations should not be confused with other negotiations specific to the program, such as TELNET negotiations, which would occur later, once control is returned to the application. /* * I should first define 'negotiation line', 'acceptance line', * and 'disconnect' to describe the following... */ When the connection is made, the server writes a line of 10 to 999 octets, composed of ASCII characters, terminating with CRLF, to the client. This line must begin with the eight characters 'S' 'K' 'R' SPACE h t o SPACE where h, t, and o are three decimal digits '0'-'9' (hundreds, tens, and ones places), with leading a zero in the hundreds place if required, specifying the length of this line, counting the CRLF at the end. Thus the minimum length of the line is 10. The reason for putting the length of the line in the front is so that the client can first read 8 characters, and then read the rest of the line, but not try to read any characters beyond that size. After the "SKR hto " follow zero or more words of the regexp form [A-Za-z0-9+][A-Za-z0-9/.+-]* separated by one or more SPACE characters. Case matters. These words specify protocols, and should registered with strick@yak.net, or begin with "x-" for experimental protocols. By sending this line, the server volunteers to server this protocol skronked with any of the listed protocols. The server should list the protocols in order of preference, its favored protocols first. The client reads this line, chooses one (or more) protocols, and responds with a similar line, listing only the protocol(s) that it chooses to use, in a specific "stacking" order, from the first protocol applied to the last. For instance, if it chooses "gzip" compression followed by "des" encryption, it should list them in the order "gzip des". Some protocols choices may not be compatible, and some protocol choices may not have stacking order; this will have to be described when the protocols are defined. If the client does not like any of the choices offered, it may hang up the connection, instead of replying with a line. If the server accepts the protocol the client chose, it responds with 8 characters 'S' 'K' 'R' SPACE 'O' 'K' CR LF If not, it may either disconnect the connection, or it may send another initial negotiation line, which should be different from the initial line offered (probably with fewer options for the client to choose). If the negotiation is accepted, what happens next depends on the accepted protocols, and on the actions of the rest of the program. Typically a selected protocol may have to do some more negotiation or trading of data before control is returned to the application. And later reads and writes from the application to the skronked socket may be intercepted and frobbed. PRIMORDIAL PROTOCOLS For stream encryption: /* needs work */ A simple initial protocol named "dh/idea.1". Use Diffee-Hellman key exchange from RSAREF 2.0. Let the server declare the R_DH_PARAMS, and the size of things. Use IDEA encryption in CFB mode from PGP 2.6. No authentication -- susceptible to man-in-the-middle attacks at connection time. For authentication: /* needs lots of work */ A simple initial protocol named "auth-pgp.1" Use PGP public keys and certificates to create a web of trust and thereby authenticate hosts. Can be combined with "dh/idea.1" or used separately. (This probably requires having secret key pass phrases on multiuser machines, so it's one small step forward.) -------------------------------- END $Header: /x/nepal/x/yak/strick/work/skronk-write/RCS/skronk.proto,v 1.3 95/02/05 01:18:49 strick Exp Locker: strick $
...
/* "Skronk" is a musical term, for a new-york-ish free-jazz * massively saxaphonish kind of music, e.g. John Zorn */
---- THE UDP PROTOCOL BEGINS HERE ----
THE SKRONK MAP DAEMON
A skronk map daemon is a UDP service that tells what skronked services are available from a site, and what alternate TCP server port numbers they use.
UDP won't get through most firewalls. Build in support for non-transparent firewalls (ie: telnet gatekeeper, c sys port). Handle getting access to skronked protocols by using the standard telnet port and logging in as 'skronk' to get access to a service multiplexer. Just some suggestions to deal with realities of availability. ... sdw -- Stephen D. Williams 25Feb1965 VW,OH sdw@lig.net http://www.lig.net/sdw Senior Consultant 513-865-9599 FAX/LIG 513.496.5223 OH Page BA Aug94-Feb95 OO R&D AI:NN/ES crypto By Buggy: 2464 Rosina Dr., Miamisburg, OH 45342-6430 Firewall/WWW srvrs ICBM/GPS: 39 38 34N 84 17 12W home, 37 58 41N 122 01 48W wrk Pres.: Concinnous Consulting,Inc.;SDW Systems;Local Internet Gateway Co.28Jan95
Stephen D Williams wrote: | > THE SKRONK MAP DAEMON | > | > A skronk map daemon is a UDP service that tells what skronked services are | > available from a site, and what alternate TCP server port numbers they | > use. | | UDP won't get through most firewalls. | | Build in support for non-transparent firewalls (ie: telnet gatekeeper, | c sys port). | | Handle getting access to skronked protocols by using the standard telnet | port and logging in as 'skronk' to get access to a service multiplexer. | | Just some suggestions to deal with realities of availability. I was going to say some similar things about firewalls, but then decided that Strick is doing the right thing. If the firewall wants to offer skronk'd services, it can respond to the UDP packet, and offer up services, presumably through relays. The relay/proxy programs for these protocols already exist. So you can reuse them to carry encrypted traffic through your firewall. Why build a new set of proxies that have to be checked for correctness? Of course, letting encrypted traffic through your firewall will upset those people who thought they can virus/porn scan at the firewall. Such scanners are almost always broken anyway. Adam -- "It is seldom that liberty of any kind is lost all at once." -Hume
Stephen D Williams wrote:
| > THE SKRONK MAP DAEMON
...
I was going to say some similar things about firewalls, but then decided that Strick is doing the right thing. If the firewall wants to offer skronk'd services, it can respond to the UDP packet, and offer up services, presumably through relays.
The relay/proxy programs for these protocols already exist. So you can reuse them to carry encrypted traffic through your firewall. Why build a new set of proxies that have to be checked for correctness?
I wasn't talking about replacing the proxy's, but 'playing' them instead of assuming you could connect directly between the skronked program and it's server. In otherwords: Since it looks like we're stuck with visible proxy firewalls for the forseeable future, we need to start codifying proxy-relay semantics into new protocol preambles. This gets us back to more or less transparent network services. This is especially true of non-mainstream methods of access.
Of course, letting encrypted traffic through your firewall will upset those people who thought they can virus/porn scan at the firewall. Such scanners are almost always broken anyway.
Adam
-- "It is seldom that liberty of any kind is lost all at once." -Hume
-- Stephen D. Williams 25Feb1965 VW,OH sdw@lig.net http://www.lig.net/sdw Senior Consultant 513-865-9599 FAX/LIG 513.496.5223 OH Page BA Aug94-Feb95 OO R&D AI:NN/ES crypto By Buggy: 2464 Rosina Dr., Miamisburg, OH 45342-6430 Firewall/WWW srvrs ICBM/GPS: 39 38 34N 84 17 12W home, 37 58 41N 122 01 48W wrk Pres.: Concinnous Consulting,Inc.;SDW Systems;Local Internet Gateway Co.28Jan95
Adam Shostack says:
I was going to say some similar things about firewalls, but then decided that Strick is doing the right thing. If the firewall wants to offer skronk'd services, it can respond to the UDP packet, and offer up services, presumably through relays.
I was going to mention something about not putting excess thought into the fifth or sixth "encrypt tcp connections" hack I'm aware of, but... Perry
sdw@lig.net (Stephen D. Williams) wrote:
UDP won't get through most firewalls.
I'm working on a program that gets around this. It creates a IP tunnel by setting up a SLIP interface on a encrypted TCP stream and routes packets through that. It's not completely finished but it does work. Send me mail if you want it.
Matthew J Ghio says:
sdw@lig.net (Stephen D. Williams) wrote:
UDP won't get through most firewalls.
I'm working on a program that gets around this. It creates a IP tunnel by setting up a SLIP interface on a encrypted TCP stream and routes packets through that. It's not completely finished but it does work. Send me mail if you want it.
Pardon but... why? Whats the reason for wanting to do this? If a firewall has been set up to stop UDP, then it should stop UDP. If the firewall has not been set up to stop UDP, or has a mechanism like the experimental versions of "socks" currently being played with that relay UDP, then there is no reason to want to do the above. I don't really understand what the idea is here. Perry
"Perry E. Metzger" <perry@imsi.com> writes:
Pardon but... why? Whats the reason for wanting to do this?
If a firewall has been set up to stop UDP, then it should stop UDP. If the firewall has not been set up to stop UDP, or has a mechanism like the experimental versions of "socks" currently being played with that relay UDP, then there is no reason to want to do the above. I don't really understand what the idea is here.
Presumably you would only let trusted people tunnel through your firewall.
Matthew J Ghio says:
"Perry E. Metzger" <perry@imsi.com> writes:
Pardon but... why? Whats the reason for wanting to do this?
If a firewall has been set up to stop UDP, then it should stop UDP. If the firewall has not been set up to stop UDP, or has a mechanism like the experimental versions of "socks" currently being played with that relay UDP, then there is no reason to want to do the above. I don't really understand what the idea is here.
Presumably you would only let trusted people tunnel through your firewall.
Fine -- then packet filter on your firewall. Of course, you can't really trust the IP addresses anyway -- you need something IPSP-like if you actually want to trust outside hosts (swIPe does nicely as a stopgap). And even if one wanted to move packets through a firewall over TCP, why use SLIP encapsulation? It was designed for unreliable links -- on a reliable link, you can save lots of grief by just sending the packet -- total length of an IP datagram is included inside the datagram, thus rendering further encapsulation unnecessary. Perry
Matthew J Ghio says:
sdw@lig.net (Stephen D. Williams) wrote:
UDP won't get through most firewalls.
I'm working on a program that gets around this. It creates a IP tunnel by setting up a SLIP interface on a encrypted TCP stream and routes packets through that. It's not completely finished but it does work. Send me mail if you want it.
Pardon but... why? Whats the reason for wanting to do this?
If a firewall has been set up to stop UDP, then it should stop UDP. If the firewall has not been set up to stop UDP, or has a mechanism like the experimental versions of "socks" currently being played with that relay UDP, then there is no reason to want to do the above. I don't really understand what the idea is here.
Perry
Actually, tunneling through a telnet connection on an application-level firewall does have its place, especially when the firewall's granularity of authentication is designed only to bind authorized people to telnet connections. This way, the firewall need only enforce a very simple access control model (which is easier to verify is working correctly) and need make very few authentication decisions on a per-packet basis. The down side (which is why I don't do this myself) is that you have to be careful that the external end of the tunnel does not forward IP packets from the rest of the net and is otherwise reasonably secure, or one such connection is enough to eliminate any security benefits the firewall might otherwise have offered. It's not clear there's much a telnet firewall can do to prevent tunnels, however, so we might as well at least make them secure as we can. -matt
participants (6)
-
Adam Shostack -
Matt Blaze -
Matthew J Ghio -
Perry E. Metzger -
sdw@lig.net -
strick at The Yak