Self-hosted service
cminyard/ser2net avatar
cminyard/ser2net

ser2net turns serial ports into network connectors

Serial to network interface, allows TCP/UDP to serial port connections

627 stars97 forksCGPL-2.0

At a glance

What is it?
ser2net is a small C program that lets network clients reach a serial port, an IPMI Serial over LAN console, or anything else the gensio library can connect to. It is configured in YAML with accepter and connector lines, it speaks raw TCP or telnet with RFC 2217, and it delegates encryption, mDNS and IPMI to the gensio library it is built on.
Who is it for?
ser2net fits a lab or datacenter with hardware serial consoles and IPMI SOL machines that need a socket interface, and it does not fit an environment where you need a full terminal server with multi-user session management, since ser2net is a single daemon with a small configuration surface and no session concept.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 70 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two lines of configuration: accepter and connector

ser2net is described in the README as a program for allowing connections between gensio accepters and gensio connectors. That definition is terse but it is the whole architecture. An accepter is the network side, the thing that listens. A connector is the device side, the thing you reach.

The README says this is generally a network connection to a serial port or to an IPMI Serial Over LAN connection, while noting there are lots of gensios and lots of options. The reference to the gensio(5) man page for the full list is the honest answer to how extensible it is: ser2net is a veneer over gensio, with added features, and the accepter and connector lines in the configuration file are directly the strings the gensio library uses for accepting and making connections.

A minimal configuration looks like this:

yaml
  connection: &my-port
        accepter: tcp,3001
        connector: serialdev,/dev/ttyUSB0,115200N81

The YAML anchor is a convenience so that several connections can share a definition. The accepter opens a TCP port, and the connector points at a device node with a serial line setting of 115200 baud, eight data bits and one stop bit. With this in place ser2net opens a TCP port and clients can type at it.

The configuration file is YAML, the format is documented in the ser2net.yaml(5) man page, and an example file ships with the program as ser2net.yaml. The operational documentation is the ser2net(8) man page, and the source tree holds the man page sources as ser2net.8 and ser2net.yaml.5.

The gensio library carries the features, not ser2net

ser2net needs three libraries to build: libyaml, libxcrypt and gensio. The first two are ordinary system dependencies, but the third is the one that matters, because the README says a lot of the capabilities of ser2net, specifically crypto, mDNS and IPMI, come from gensio, so it must be compiled correctly for those to work.

That creates a dependency risk. The gensio library may be available on your distribution, or it may not, and it may be old and missing things you need. On Ubuntu the README suggests the distro package will probably do:

bash
  apt install libgensio-dev

Otherwise the library is available as a tarball in the ser2net sourceforge files, or from the gensio repository on GitHub. So an install can end up with three different gensio versions in play: the distro one, a sourceforge tarball, and a git checkout. Since the crypto and IPMI behaviour lives in gensio, mixing a stale gensio with a current ser2net is a plausible way to end up with a feature that is present in the docs and absent at runtime.

The other two dependencies are simpler. On Ubuntu, libyaml and libxcrypt come from a single apt line:

bash
  apt install libyaml-dev libcrypt-dev

The gensio project also ships companion programs. The README mentions gensiot and gtlssh for encrypted connections and telnet-ssl, and describes gensiot as the tool to use for plain command line access.

Building from git needs the reconf script

The build system is a normal autoconf system, and the README says so without elaborating. If you do not know autoconf, it points at the INSTALL file in the tree or tells you to look it up.

One detail matters for anyone working from a git checkout rather than a release tarball. If you get the source directly from git, the build infrastructure is not included, and there is a script named reconf in the main directory that creates it. Without running it, a git clone has no configure script to run.

The source tree is laid out the way you would expect for a mature C project. The top level is full of .c and .h pairs, one per concern: ser2net.c and ser2net.h for the program itself, controller.c for connection control, dataxfer.c for moving data, port.c and portconfig.c for the port model, portinfo.c for status reporting, readconfig.c and yamlconf.c for configuration parsing, defaults.c for built-in defaults, auth.c for authentication, rotator.c for a rotation feature, led.c and led_sysfs.c for LED handling, mdns.c for mDNS, gbuf.c for buffers, fileio.c for file access, timeproc.c for timers and trace.c for tracing.

Service integration is present too, with ser2net.service.in and ser2net.init templates plus an install script, and there is a tests directory, a ChangeLog, a NEWS file and a SECURITY.md.

Docker support exists, but not here. The README points to a separate repository, the docker-ser2net project by jippi, for container images, which keeps the container concerns out of this tree.

Do not point the telnet command at a plain TCP accepter

The README spends a good deal of space on how clients should connect, and the reason is a genuine trap. With a configuration that uses a plain tcp accepter, ser2net opens a TCP port and that is all it does. The README says you should not use the telnet command to connect in that case, because ser2net will not do the telnet protocol and the telnet command may become confused.

The supported client for that case is gensiot:

bash
  gensiot tcp,host,3001

That connects to the port and lets you type. gensiot can also act as a pipe, attempting to do the right thing based on how it was started.

If you want the telnet protocol, you have to ask for it in the accepter, and the README is direct that this does not add much value except that the standard telnet command then works:

yaml
  connection: &my-port
        accepter: telnet,tcp,3001
        connector: serialdev,/dev/ttyUSB0,115200N81

The real value of telnet is RFC 2217, which is remote control of serial port parameters such as baud rate and stop bits. That is configured in the accepter as well:

yaml
  connection: &my-port
        accepter: telnet(rfc2217),tcp,3001
        connector: serialdev,/dev/ttyUSB0,115200N81

With that accepter, gensiot becomes the client that can change the port settings:

bash
  gensiot telnet(rfc2217),tcp,host,3001

The catch is that the standard telnet command does not do RFC 2217, so a client that understands the protocol is required. The README lists the clients that do: gensiot, gtlssh, and, as far as the author knows, kermit.

IPMI SOL works, but the credential handling is your problem

ser2net can connect to IPMI Serial over LAN capable systems, which lets you reach a machine that speaks sockets rather than run a serial cable to it. The README is upfront that this uses OpenIPMI, so you need to know how to make an OpenIPMI connection to the remote system, and that this can be rather complicated.

The configuration shape is the same accepter and connector pair:

yaml
  connection: &ipmicon1
    accepter: telnet,tcp,3022
    connector: ipmisol,lan -U <userid> -P <password> <ipmi BMC IP>,115200

The password appears in the connector line, and the README says plainly that if you put passwords in the ser2net configuration file it becomes a security issue and the file should be readable only by the user that runs ser2net. There is a better option in the same paragraph: ways exist to insert data from files, so the password does not have to sit in the clear in the main configuration file. The ser2net.yaml(5) man page has the details.

The README also warns that configuration of IPMI on the remote system is not for the faint of heart, and that the BMC userid and password in the example are obviously placeholders.

For the opposite direction, connecting to a local serial port device that is really remote, the README points at a Cyclades project that connects to ser2net using RFC 2217.

Threading is a flag, and scaling depends on epoll

ser2net runs single threaded by default and takes a thread count on the command line:

The thread count is given on the command line with -t and a number of threads, so the flag reads -t 8 for eight workers.

The README says that on modern Linux systems it uses epoll to avoid the thundering herd problem, so it should be quite scalable, and that it runs reconfigurations in a separate thread to avoid a reconfiguration blocking things up. The second point is the one worth remembering: a configuration reload does not stall the connections, because the reload runs somewhere else.

If you would rather not have threads in the binary at all, there is a configure option for that:

The configure option that disables threads is spelled --with-pthreads=no in the README.

That is a build-time decision rather than a runtime one, which is worth noting for anyone packaging ser2net for an embedded image where the thread library is unwanted.

Encryption and authentication are inherited from gensio rather than implemented here. The README says that since gensios support encryption and authentication, these are available to ser2net, that gensiot and gtlssh can do the encryption, and that telnet-ssl can also be used. For programmatic access there is an ssl gensio layer, and the clientauth option gives mutual authentication so that normal SSL performs two-way authentication. Beyond that, richer schemes such as password based authentication exist, though the README excerpt ends before describing them.

A mature C daemon with its documentation in the man pages

ser2net has the shape of a tool that has been in production for a long time. The C source is split into focused files, there is a ChangeLog, a NEWS file, an AUTHORS file, a SECURITY.md and a COPYING file, the configuration is YAML rather than a bespoke format, and the docs are proper man pages: ser2net(8) for using the program and ser2net.yaml(5) for the configuration file.

The GPL-2.0 licensing matters for anyone shipping it inside a product or appliance, since it carries obligations that a permissive licence would not. There is also a separate docker-ser2net repository for container use, so the packaging work is not part of this tree.

Maintenance is steady rather than fast. The published releases are v4.6.8 on 2026-08-03, v4.6.7 on 2026-02-06 and v4.6.6 on 2025-11-16, and the last push was on 2026-08-14. The repository is not archived.

One gap in the documentation is worth flagging for anyone evaluating it. The README refers you to the man pages for the configuration details, so the practical cost of learning the tool is reading ser2net.yaml(5) rather than the README, and the README itself does not enumerate the full set of accepter and connector types. The gensio(5) page is where that list lives.

Another practical limit: ser2net is a serial port bridge, not a terminal server. It exposes a socket to a device. There is no session multiplexing, no per-user authentication policy of its own beyond the gensio layers, and no recording, which is the difference between it and the kind of console management tool a data centre team often has in mind.

Editorial conclusion

ser2net fits a lab or datacenter with hardware serial consoles and IPMI SOL machines that need a socket interface, and it does not fit an environment where you need a full terminal server with multi-user session management, since ser2net is a single daemon with a small configuration surface and no session concept. Before you install it, confirm that the gensio library on your distribution is new enough, because the crypto, mDNS and IPMI behaviour lives in gensio rather than in ser2net, and build from the git tree with the reconf script if your package is old. The project is GPL-2.0 licensed, release v4.6.8 was published on 2026-08-03, and the last push was on 2026-08-14.

Frequently asked questions

How do I configure a serial port in ser2net?

A connection entry pairs an accepter with a connector. The accepter opens the network side, for example accepter: tcp,3001, and the connector names the device, for example connector: serialdev,/dev/ttyUSB0,115200N81. The format is documented in the ser2net.yaml(5) man page and the accepter and connector strings are the ones the gensio library uses.

Which client should I use to connect to ser2net?

For a plain tcp accepter the README says to use gensiot rather than the telnet command, since ser2net does not do the telnet protocol in that case. For RFC 2217, which allows changing port parameters such as baud rate, the accepter must be telnet(rfc2217) and the client must speak the protocol, for example gensiot telnet(rfc2217),tcp,host,3001.

What libraries does ser2net need to build?

The README lists libyaml, libxcrypt and gensio. On Ubuntu libyaml-dev and libcrypt-dev cover the first two, and libgensio-dev may be enough for gensio, though the README warns the distro copy may be old and missing things you need, and that the crypto, mDNS and IPMI capabilities come from gensio.

Can ser2net reach an IPMI Serial over LAN console?

Yes. The README says ser2net supports connections to IPMI SOL capable systems through OpenIPMI, using an ipmisol connector such as ipmisol,lan -U <userid> -P <password> <ipmi BMC IP>,115200. It warns that storing passwords in the configuration file is a security issue and that the file should be readable only by the user running ser2net.

Official sources

  1. cminyard/ser2net on GitHub
  2. Issues
  3. License: GPL-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cminyard-ser2net.svg)](https://hysenlabs.com/projects/cminyard-ser2net)

Was this useful?