<!doctype html><htmllang=enclass=no-js><head><metacharset=utf-8><metaname=viewportcontent="width=device-width,initial-scale=1"><metaname=descriptioncontent="An open source, self-hosted implementation of the Tailscale control server."><metaname=authorcontent="Headscale authors"><linkhref=https://juanfont.github.io/headscale/development/usage/getting-started/rel=canonical><linkhref=../../setup/upgrade/rel=prev><linkhref=../connect/android/rel=next><linkrel=iconhref=../../assets/favicon.png><metaname=generatorcontent="mkdocs-1.6.1, mkdocs-material-9.7.0"><title>Getting started - Headscale</title><linkrel=stylesheethref=../../assets/stylesheets/main.618322db.min.css><linkrel=stylesheethref=../../assets/stylesheets/palette.ab4e12ef.min.css><linkrel=preconnecthref=https://fonts.gstatic.comcrossorigin><linkrel=stylesheethref="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback"><style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style><script>__md_scope=newURL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script><metaproperty=og:typecontent=website><metaproperty=og:titlecontent="Getting started - Headscale"><metaproperty=og:descriptioncontent="An open source, self-hosted implementation of the Tailscale control server."><metaproperty=og:imagecontent=https://juanfont.github.io/headscale/development/assets/images/social/usage/getting-started.png><metaproperty=og:image:typecontent=image/png><metaproperty=og:image:widthcontent=1200><metaproperty=og:image:heightcontent=630><metacontent=https://juanfont.github.io/headscale/development/usage/getting-started/property=og:url><metaproperty=twitter:cardcontent=summary_large_image><metaproperty=twitter:titlecontent="Getting started - Headscale"><metaproperty=twitter:descriptioncontent="An open source, self-hosted implementation of the Tailscale control server."><metaproperty=twitter:imagecontent=https://juanfont.github.io/headscale/development/assets/images/social/usage/getting-started.png></head><bodydir=ltrdata-md-color-scheme=defaultdata-md-color-primary=whitedata-md-color-accent=indigo><inputclass=md-toggledata-md-toggle=drawertype=checkboxid=__drawerautocomplete=off><inputclass=md-toggledata-md-toggle=searchtype=checkboxid=__searchautocomplete=off><labelclass=md-overlayfor=__drawer></label><divdata-md-component=skip><ahref=#getting-startedclass=md-skip> Skip to content </a></div><divdata-md-component=announce></div><divdata-md-color-scheme=defaultdata-md-component=outdatedhidden></div><headerclass=md-headerdata-md-component=header><navclass="md-header__inner md-grid"aria-label=Header><ahref=../..title=Headscaleclass="md-header__button md-logo"aria-label=Headscaledata-md-component=logo><imgsrc=../../logo/headscale3-dots.svgalt=logo></a><labelclass="md-header__button md-icon"for=__drawer><svgxmlns=http://www.w3.org/2000/svgviewbox="0 0 24 24"><pathd="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg></label><divclass=md-header__titledata-md-component=header-title><divclass=md-header__ellipsis><divclass=md-header__topic><spanclass=md-ellipsis> Headscale </span></div><divclass=md-header__topicdata-md-component=header-topic><spanclass=md-ellipsis> Getting started </span></div></div></div><formclass=md-header__optiondata-md-component=palette><inputclass=md-optiondata-md-color-mediadata-md-color-scheme=defaultdata-md-color-primary=whitedata-md-color-accent=indigoaria-label="Switch to dark mode"type=radioname=__paletteid=__palette_0><labelclass="md-header__button md-icon"title="Switch to dark mode"for=__palette_1hidden><svgxmlns=http://www.w3.org/2000/svgviewbox="0 0 24 24"><pathd="M128a44000-444400044440004-444000-4-
</span></code></pre></div></div><divclass=tabbed-block><divclass="language-shell highlight"><pre><span></span><code><spanid=__span-1-1><aid=__codelineno-1-1name=__codelineno-1-1href=#__codelineno-1-1></a><spanclass=c1># Show help</span>
</span></code></pre></div></div></div></div><divclass="admonition note"><pclass=admonition-title>Manage headscale from another local user</p><p>By default only the user <code>headscale</code> or <code>root</code> will have the necessary permissions to access the unix socket (<code>/var/run/headscale/headscale.sock</code>) that is used to communicate with the service. In order to be able to communicate with the headscale service you have to make sure the unix socket is accessible by the user that runs the commands. In general you can achieve this by any of the following methods:</p><ul><li>using <code>sudo</code></li><li>run the commands as user <code>headscale</code></li><li>add your user to the <code>headscale</code> group</li></ul><p>To verify you can run the following command using your preferred method:</p><divclass="language-shell highlight"><pre><span></span><code><spanid=__span-2-1><aid=__codelineno-2-1name=__codelineno-2-1href=#__codelineno-2-1></a>headscale<spanclass=w></span>users<spanclass=w></span>list
</span></code></pre></div></div><h2id=manage-headscale-users>Manage headscale users<aclass=headerlinkhref=#manage-headscale-userstitle="Permanent link">¶</a></h2><p>In headscale, a node (also known as machine or device) is always assigned to a headscale user. Such a headscale user may have many nodes assigned to them and can be managed with the <code>headscale users</code> command. Invoke the built-in help for more information: <code>headscale users --help</code>.</p><h3id=create-a-headscale-user>Create a headscale user<aclass=headerlinkhref=#create-a-headscale-usertitle="Permanent link">¶</a></h3><divclass="tabbed-set tabbed-alternate"data-tabs=2:2><inputchecked=checkedid=__tabbed_2_1name=__tabbed_2type=radio><inputid=__tabbed_2_2name=__tabbed_2type=radio><divclass=tabbed-labels><labelfor=__tabbed_2_1>Native</label><labelfor=__tabbed_2_2>Container</label></div><divclass=tabbed-content><divclass=tabbed-block><divclass="language-shell highlight"><pre><span></span><code><spanid=__span-3-1><aid=__codelineno-3-1name=__codelineno-3-1href=#__codelineno-3-1></a>headscale<spanclass=w></span>users<spanclass=w></span>create<spanclass=w></span><USER>
</span></code></pre></div></div></div></div><h2id=register-a-node>Register a node<aclass=headerlinkhref=#register-a-nodetitle="Permanent link">¶</a></h2><p>One has to register a node first to use headscale as coordination with Tailscale. The following examples work for the Tailscale client on Linux/BSD operating systems. Alternatively, follow the instructions to connect <ahref=../connect/android/>Android</a>, <ahref=../connect/apple/>Apple</a> or <ahref=../connect/windows/>Windows</a> devices.</p><h3id=normal-interactive-login>Normal, interactive login<aclass=headerlinkhref=#normal-interactive-logintitle="Permanent link">¶</a></h3><p>On a client machine, run the <code>tailscale up</code> command and provide the FQDN of your headscale instance as argument:</p><divclass="language-shell highlight"><pre><span></span><code><spanid=__span-7-1><aid=__codelineno-7-1name=__codelineno-7-1href=#__codelineno-7-1></a>tailscale<spanclass=w></span>up<spanclass=w></span>--login-server<spanclass=w></span><YOUR_HEADSCALE_URL>
</span></code></pre></div><p>Usually, a browser window with further instructions is opened and contains the value for <code><YOUR_MACHINE_KEY></code>. Approve and register the node on your headscale server:</p><divclass="tabbed-set tabbed-alternate"data-tabs=4:2><inputchecked=checkedid=__tabbed_4_1name=__tabbed_4type=radio><inputid=__tabbed_4_2name=__tabbed_4type=radio><divclass=tabbed-labels><labelfor=__tabbed_4_1>Native</label><labelfor=__tabbed_4_2>Container</label></div><divclass=tabbed-content><divclass=tabbed-block><divclass="language-shell highlight"><pre><span></span><code><spanid=__span-8-1><aid=__codelineno-8-1name=__codelineno-8-1href=#__codelineno-8-1></a>headscale<spanclass=w></span>nodes<spanclass=w></span>register<spanclass=w></span>--user<spanclass=w></span><USER><spanclass=w></span>--key<spanclass=w></span><YOUR_MACHINE_KEY>
</span></code></pre></div></div></div></div><h3id=using-a-preauthkey>Using a preauthkey<aclass=headerlinkhref=#using-a-preauthkeytitle="Permanent link">¶</a></h3><p>It is also possible to generate a preauthkey and register a node non-interactively. First, generate a preauthkey on the headscale instance. By default, the key is valid for one hour and can only be used once (see <code>headscale preauthkeys --help</code> for other options):</p><divclass="tabbed-set tabbed-alternate"data-tabs=5:2><inputchecked=checkedid=__tabbed_5_1name=__tabbed_5type=radio><inputid=__tabbed_5_2name=__tabbed_5type=radio><divclass=tabbed-labels><labelfor=__tabbed_5_1>Native</label><labelfor=__tabbed_5_2>Container</label></div><divclass=tabbed-content><divclass=tabbed-block><divclass="language-shell highlight"><pre><span></span><code><spanid=__span-10-1><aid=__codelineno-10-1name=__codelineno-10-1href=#__codelineno-10-1></a>headscale<spanclass=w></span>preauthkeys<spanclass=w></span>create<spanclass=w></span>--user<spanclass=w></span><USER_ID>
</span></code></pre></div></div></div></div><p>The command returns the preauthkey on success which is used to connect a node to the headscale instance via the <code>tailscale up</code> command:</p><divclass="language-shell highlight"><pre><span></span><code><spanid=__span-12-1><aid=__codelineno-12-1name=__codelineno-12-1href=#__codelineno-12-1></a>tailscale<spanclass=w></span>up<spanclass=w></span>--login-server<spanclass=w></span><YOUR_HEADSCALE_URL><spanclass=w></span>--authkey<spanclass=w></span><YOUR_AUTH_KEY>