{"id":2690,"date":"2026-04-20T17:33:39","date_gmt":"2026-04-20T15:33:39","guid":{"rendered":"http:\/\/www.gatchev.info\/blog\/?p=2690"},"modified":"2026-04-20T17:33:39","modified_gmt":"2026-04-20T15:33:39","slug":"a-low-tech-trick-with-sshfs","status":"publish","type":"post","link":"http:\/\/www.gatchev.info\/blog\/?p=2690","title":{"rendered":"A low-tech trick with sshfs"},"content":{"rendered":"<p>Sometimes old, low-tech sysadmin tricks do excellent job. \ud83d\ude42<\/p>\n<p>A friend of mine asked for help. Time had came for his company to grow up, and it had opened several offices across Europe. However, their IT system wasn&#8217;t up to that.<\/p>\n<p>Their specialized software currently ran on a local server in their office. Now, every office had a server &#8211; but they had to use together a central database. The software could share a database between several instances, but access to it was built directly in the executable and required a local path. The company behind it had offered to add a client-server database model, but the cost was prohibitive.<\/p>\n<p>Luckily, all of it ran over Linux, which has a huge set of tools for everything. I decided on a very simple and dumb solution. Mounted the directory with the database as local on the office servers through <code>sshfs<\/code>. It uses <code>ssh<\/code> as a transport agent, so the protection of data through Internet is very good.<br \/>\n<code><br \/>\nsshfs database_user@database-server.mycompany.com:\/some\/path\/to\/database \/local\/mount\/path<br \/>\n<\/code><br \/>\nTo avoid the need for <code>ssh<\/code> login, I generated (as the user that mounts the directory) a key for every remote server:<br \/>\n<code><br \/>\nsu db_dir_mount_user<br \/>\nssh-keygen -t rsa -b 4096<br \/>\n<\/code><br \/>\n(It asks for some action from you, and finally generates the key in the <code>.ssh<\/code> subdirectory in the home directory of the user, as two files: <code>id_rsa<\/code> and <code>id_rsa.pub<\/code>.)<\/p>\n<p>Then, I authorized these keys at the server with the database. I went to it, and there (as database_user) copied the <code>id_rsa.pub<\/code> file from the remote server to the server with the database, and added it to the file <code>.ssh\/authorized_keys<\/code>:<br \/>\n<code><br \/>\nsu database_user<br \/>\nrsync -avz db_dir_mount_user@local-server-1.mycompany.com:\/home\/db_dir_mount_user\/.ssh\/id_rsa.pub .ssh\/local-server-1.id_rsa.pub<br \/>\ncat local-server-1.id_rsa.pub &gt;&gt; authorized_keys<br \/>\n<\/code><br \/>\nSo far, so well. However, when I started <code>sshfs<\/code>, it refused to work with a message:<br \/>\n<code><br \/>\nfuse: device not found, try 'modprobe fuse' first<br \/>\n<\/code><br \/>\nTurned out, the local office servers with the software were actually LXC containers. The company had one physical (well, and one backup \ud83d\ude42 ) server per office, with several LXC containers running different things on it. Both the software container and the mother OS had <code>fuse<\/code> (which is required by <code>sshfs<\/code>) installed, but that was not enough.<\/p>\n<p>The problem turned out to be a <code>fuse<\/code> device missing from the <code>\/dev<\/code> directory. Which was easy to solve:<br \/>\n<code><br \/>\nmknod \/dev\/fuse c 10 229<br \/>\n<\/code><br \/>\nAfter that, everything went without a glitch. The experiments showed that the query times are low enough for production usage.<\/p>\n<p>Yes, if this company continues to grow, rewriting the database communication as a client-server model will be unavoidable. However, this trick gave them some time to grow up more and find the money needed. \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes old, low-tech sysadmin tricks do excellent job. \ud83d\ude42 A friend of mine asked for help. Time had came for his company to grow up, and it had opened several offices across Europe. However, their IT system wasn&#8217;t up to that. Their specialized software currently ran on a local server in their office. Now, every [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"hide_page_title":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2690"}],"collection":[{"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2690"}],"version-history":[{"count":4,"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2690\/revisions"}],"predecessor-version":[{"id":2694,"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2690\/revisions\/2694"}],"wp:attachment":[{"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2690"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2690"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.gatchev.info\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2690"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}