{"id":689,"date":"2026-02-16T18:39:52","date_gmt":"2026-02-16T17:39:52","guid":{"rendered":"https:\/\/xpam.pl\/blog\/?p=689"},"modified":"2026-02-16T18:39:52","modified_gmt":"2026-02-16T17:39:52","slug":"conencting-to-safeguard-rdp-via-freerdp-on-linux","status":"publish","type":"post","link":"https:\/\/xpam.pl\/blog\/?p=689","title":{"rendered":"Conencting to SafeGuard RDP via FreeRDP on Linux"},"content":{"rendered":"<p>On Linux, Remmina\/KRCD\/freerdp do not work out of the box with <a href=\"https:\/\/www.oneidentity.com\/products\/one-identity-safeguard-remote-access\/\">SafeGuard remote access<\/a>.<\/p>\n<p>When you connect, see the SafeGuard welcome\/approval screen, click accept, and then&#8230; the window either shows \"no auth n\/a\" and disconnects, or freezes indefinitely.<\/p>\n<p>What's actually happening?<\/p>\n<p>The SafeGuard bastion uses a two-stage connection:<\/p>\n<p>1. <strong>First hop<\/strong> &#8212; your client connects to the bastion proxy over TLS. The vault token in the username authenticates you. The bastion shows a welcome screen.<br \/>\n2. <strong>Second hop<\/strong> &#8212; after you accept the welcome screen, the bastion sends an RDP <strong>Server Redirection PDU<\/strong> containing credentials (username, domain, password) for the target machine. Your FreeRDP client follows the redirect and establishes a new connection, this time with <strong>NLA<\/strong> (Network Level Authentication) required by the target.<\/p>\n<p>&nbsp;<\/p>\n<p>When FreeRDP performs NLA on the redirect, it uses SPNEGO which tries Kerberos first. If the KDC for the target domain is unreachable from your machine (common when the domain controller is behind the bastion), Kerberos times out before falling back to NTLM.<br \/>\nWorse: FreeRDP 3.14 and 3.15 (the versions shipped with Debian Trixie and the Remmina snap as of early 2026) <strong>crash with SIGABRT<\/strong> instead of falling back to NTLM. This is fixed in FreeRDP 3.22+.<\/p>\n<p>To make everything work on Trixie, we need:<br \/>\n1. <strong>FreeRDP nightly (3.22+)<\/strong> which properly falls back from Kerberos to NTLM<br \/>\n2. <strong>A minimal krb5.conf<\/strong> that disables DNS-based KDC discovery, so Kerberos fails instantly instead of hanging.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Installing FreeRDP nightly on Debian Trixie<\/strong><\/p>\n<p>Add the nightly repository and GPG key (as root):<\/p>\n<pre><code class=\"language-bash\">wget -qO- http:\/\/pub.freerdp.com\/repositories\/ADD6BF6D97CE5D8D.asc \\\n\u00a0| gpg --dearmor | sudo tee \/usr\/share\/keyrings\/freerdp-nightly.gpg &gt; \/dev\/null\n\n# Add the repository\ncat &lt;&lt;EOF | sudo tee \/etc\/apt\/sources.list.d\/freerdp-nightly.sources\nTypes: deb\nURIs: http:\/\/pub.freerdp.com\/repositories\/deb\/trixie\nSuites: freerdp-nightly\nComponents: main\nSigned-By: \/usr\/share\/keyrings\/freerdp-nightly.gpg\nEOF\n\n# Install\napt update\napt install freerdp-nightly<\/code><\/pre>\n<p>The nightly package installs to<strong> \/opt\/freerdp-nightly\/<\/strong> and does not conflict with the system FreeRDP.<\/p>\n<p><strong>The connect script<\/strong><\/p>\n<pre><code class=\"language-bash\">#!\/bin\/bash\nset -euo pipefail\n\nTOKEN=&quot;${1:?Usage: $0 &lt;vault-string&gt;}&quot;\n\n# Minimal krb5.conf that disables DNS-based KDC discovery.\n# Without this, Kerberos hangs trying to contact a KDC\nKRB5_CONF=$(mktemp)\ntrap &quot;rm -f &#039;$KRB5_CONF&#039;&quot; EXIT\ncat &gt; &quot;$KRB5_CONF&quot; &lt;&lt;&#039;EOF&#039;\n[libdefaults]\n\u00a0\u00a0\u00a0dns_lookup_kdc = false\n\u00a0\u00a0\u00a0dns_lookup_realm = false\n\u00a0\u00a0\u00a0udp_preference_limit = 0\n\u00a0\u00a0\u00a0kdc_timeout = 1\nEOF\n\nLD_LIBRARY_PATH=\/opt\/freerdp-nightly\/lib \\\nKRB5_CONFIG=&quot;$KRB5_CONF&quot; \\\n\/opt\/freerdp-nightly\/bin\/xfreerdp3 \\\n\u00a0\/v:bastion.example.com:4444 \\\n\u00a0\/u:&quot;$TOKEN&quot; \\\n\u00a0\/p: \/d: \\\n\u00a0\/cert:ignore \\\n\u00a0\/auth-pkg-list:ntlm \\\n\u00a0\/relax-order-checks \\\n\u00a0+clipboard \\\n\u00a0\/drive:share,&quot;$HOME\/remmina&quot;<\/code><\/pre>\n<p>Usage:<\/p>\n<pre><code class=\"language-bash\">chmod +x connect.sh\n.\/connect.sh &#039;vaultaddress~connection-string&#039;<\/code><\/pre>\n<p>What each flag does:<br \/>\n&#8211; <strong>\/u:$TOKEN<\/strong> | Full vault connection string as the username.<br \/>\n&#8211; <strong>\/p: \/d:<\/strong> | Empty password and domain (avoids interactive prompts).<br \/>\n&#8211; <strong>\/cert:ignore<\/strong> | Skip certificate validation for the bastion.<br \/>\n&#8211; <strong>\/auth-pkg-list:ntlm<\/strong> | Tell SPNEGO to prefer NTLM (Kerberos still tried by library internals, but the custom krb5.conf makes it fail fast).<br \/>\n&#8211; <strong>\/relax-order-checks<\/strong> | Tolerate out-of-order RDP packets from the bastion.<br \/>\n&#8211; <strong>+clipboard<\/strong> | Enable clipboard sharing.<br \/>\n&#8211; <strong>\/drive:share,$HOME\/remmina<\/strong> | Share a local directory into the RDP session.<\/p>\n<p>As of early 2026, both the Remmina snap (stable and edge) and the Debian Trixie package bundle FreeRDP 3.14, which crashes on the Kerberos-to-NTLM fallback during the bastion redirect.<\/p>\n<p>If you run into issues, enable trace logging by prepending WLOG_LEVEL=TRACE to the command.<\/p>\n<div class=\"wp-post-signature\">\r\n<br \/>\r\n<br \/>\r\n<img src='https:\/\/xpam.pl\/aaaaff.png' title='Moonie' \/> Cen<br \/>\r\n<a href='https:\/\/github.com\/cen1'>GitHub<\/a><br \/>\r\n<a href='https:\/\/eurobattle.net'>Eurobattle.net<\/a><br \/>\r\n<a href='https:\/\/lagabuse.com'>Lagabuse.com<\/a><br \/>\r\n<a href='https:\/\/bnetdocs.org'>Bnetdocs<\/a><br \/>\r\n<\/div>\r\n","protected":false},"excerpt":{"rendered":"<p>On Linux, Remmina\/KRCD\/freerdp do not work out of the box with SafeGuard remote access. When you connect, see the SafeGuard welcome\/approval screen, click accept, and then&#8230; the window either shows \"no auth n\/a\" and disconnects, or freezes indefinitely. What's actually happening? The SafeGuard bastion uses a two-stage connection: 1. First hop &#8212; your client connects [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,18],"tags":[],"class_list":["post-689","post","type-post","status-publish","format-standard","hentry","category-linux","category-script-magic"],"_links":{"self":[{"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=\/wp\/v2\/posts\/689","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=689"}],"version-history":[{"count":10,"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=\/wp\/v2\/posts\/689\/revisions"}],"predecessor-version":[{"id":699,"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=\/wp\/v2\/posts\/689\/revisions\/699"}],"wp:attachment":[{"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=689"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=689"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xpam.pl\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=689"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}