/dev/random

Serial console for Proxmox VMs

proxmox vm linux guide

In this blog post, I will describe how to use the serial console as the standard VM display in Proxmox VE. This will give you the ability to access a text-based shell from the web interface and the PVE host shell. This has some advantages compared to a regular text console displayed via VGA:

Configuring the Serial Hardware

A serial port has to be added to the VM hardware. It is possible to do this via the web interface, just navigate to the "hardware" tab, then click "add" -> "serial port". Restart the VM to see the changes Adding the serial port in the Proxmox web interface

Configure the VM to use the serial port

To actually see some output on the newly created serial port, the system itself has to be configured:

Configure serial output for Linux (kernel and getty)

The kernel has to be configured to use the serial console. On ubuntu 22.04, the kernel command line is passed via GRUB, so changes have to be made to the /etc/defaults/grub file:

GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200"

After making the change, run update-grub as root and restart the system.

By itself, this will only configure the kernel itself to dump log messages onto the serial console. To attach a linux terminal session onto the serial port, a getty process has to be started. On Ubuntu 22.04 (and probably later versions as well), this requires no additional configuration: systemd-getty-generator will automatically enable a corresponding systemd service for every console configured in the kernel command line. In our case, the service name is serial-getty@ttyS0.service - we can check its status later to verify that the getty generation is working. On other distributions, you might have to enable the service manually or start the getty yourself.

Optional: Configure serial console for GRUB

The GRUB bootloader itself can be configured to use the serial console by specifying the following in /etc/default/grub:

# change grub bootloader itself to use serial
GRUB_TERMINAL_INPUT="console serial"
GRUB_TERMINAL_OUTPUT="gfxterm serial"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"

Afterwards, execute update-grub as root to commit the changes.

Accessing the terminal

The serial terminal can be accessed using qm terminal $VMID. To exit the session, simply press CTRL+O. In addition, the serial console can be accessed with the web UI, by selecting xterm.js in the 'Console' menu of the VM. Some further notes:

Comparison of noVNC VGA tty vs xterm.js serial console

Appendix: Playbook

I made a small Ansible role for myself to configure new VMs automatically on the guest side. Currently, the playbook does not add the serial port, since this has to be configured on the host. Be aware that the playbook overwrites the Linux command line. I am only using this for 'blank' VMs, you might want to change it if you use a custom command line:

---
- name: Configure Linux command line
  lineinfile:
    path: /etc/default/grub
    regexp: '^GRUB_CMDLINE_LINUX_DEFAULT='
    line: 'GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200"'
  register: setup_cmdline

- name: Configure Grub serial console
  block:
    - lineinfile:
        path: /etc/default/grub
        regexp: '^GRUB_TERMINAL='
        state: absent
      register: setup_grub_terminal
    - lineinfile:
        path: /etc/default/grub
        regexp: '^GRUB_TERMINAL_INPUT='
        line: 'GRUB_TERMINAL_INPUT="console serial"'
      register: setup_grub_terminal_input
    - lineinfile:
        path: /etc/default/grub
        regexp: '^GRUB_TERMINAL_OUTPUT='
        line: 'GRUB_TERMINAL_OUTPUT="gfxterm serial"'
      register: setup_grub_terminal_output
    - lineinfile:
        path: /etc/default/grub
        regexp: '^GRUB_SERIAL_COMMAND='
        line: 'GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"'
      register: setup_grub_serial_command

- name: Update GRUB
  command:
    cmd: update-grub
  when: setup_cmdline.changed or setup_grub_terminal.changed or setup_grub_terminal_input.changed or setup_grub_terminal_output.changed or setup_grub_serial_command.changed

References

https://wiki.archlinux.org/title/working_with_the_serial_console https://www.kernel.org/doc/html/v4.14/admin-guide/serial-console.html https://blog.wataash.com/ubuntu_console/

Comments


If you have any questions or comments, please feel free to reach out to me by sending an email to blog(at)krisnet.de.