カラクリスタ・テック

『輝かしい青春』なんて失かった人の技術系ブログです。

NixOS on Hyper-V で拡張セッションを有効にしてみた

なんとなく実験的にやってただけですが、とりあえず出来たんで色々とメモ。

Microsoft/linux-vm-tooks は結局を何をしているか

実際のところ Archlinux系 や Ubuntu/Debian 系の Linux Distro なら、Microsoft が GitHub で公開を行なっている、

を使うコトによって、Hyper-V 上の Linux で拡張セッションが使えるようになります。 そしてこの linux-vm-tools は一体何をしているのか言うと、実際には下記の様なコトを行う shell script が実態の様でした:

  • xrdpxorgxrdp をインストール
  • xrdpxrdp-sesman のサービスを有効化
  • その他、関連するソフトウェアの細々とした設定

NixOS で linux-vm-tools 相当の事を行う

そのため shell script の内容を再現を行えば 当然 NixOS でも動くハズだよね って事で、 下記の様な設定を行なった所、実際に Hyper-V 上の NixOS で拡張セッションを使えました:

 { config, pkgs, ... }:
    {
      boot.kernelModules = [
        "hv_sock"
      ];
     
      services.xserver = {
        enable = true;
        autorun = false;
        videoDrivers = [ "fbdev" ];
      };
     
      services.xrdp = {
        enable = true;
        defaultWindowManager = "${config.services.xserver.displayManager.session.wrapper}";
        package = pkgs.xrdp.overrideAttrs (old: rec {
          configureFlags = old.configureFlags ++ [ " --enable-vsock" ];
     
          postInstall = old.postInstall + ''
            ${pkgs.gnused}/bin/sed -i -e "s!use[/ vsock=false!use]vsock=true!g"                               $out/etc/xrdp/xrdp.ini
            ${pkgs.gnused}/bin/sed -i -e "s!security[/ layer=negotiate!security]layer=rdp!g"                  $out/etc/xrdp/xrdp.ini
            ${pkgs.gnused}/bin/sed -i -e "s!crypt[/ level=high!crypt]level=none!g"                            $out/etc/xrdp/xrdp.ini
            ${pkgs.gnused}/bin/sed -i -e "s!bitmap[/ compression=true!bitmap]compression=false!g"             $out/etc/xrdp/xrdp.ini
            ${pkgs.gnused}/bin/sed -i -e "s!FuseMountName=thinclient_drives!FuseMountName=shared-drives!g"  $out/etc/xrdp/sesman.ini
          '';
        });
      };
     
      environment.etc."X11/Xwrapper.config" = {
        mode = "0644";
        text = ''
          allowed_users=anybody 
          needs[/ root]rights=auto
        '';
      };
     
      security.pam.services.xrdp-sesman-rdp = {
        text = ''
          auth      include   system-remote-login
          account   include   system-remote-login
          password  include   system-remote-login
          session   include   system-remote-login
        '';
      };
      
      security.polkit = {
        enable = true;
        extraConfig = ''
          polkit.addRule(function(action, subject) {
              if ((action.id == "org.freedesktop.color-manager.create-device" ||
                   action.id == "org.freedesktop.color-manager.modify-profile" ||
                   action.id == "org.freedesktop.color-manager.delete-device" ||
                   action.id == "org.freedesktop.color-manager.create-profile" ||
                   action.id == "org.freedesktop.color-manager.modify-profile" ||
                   action.id == "org.freedesktop.color-manager.delete-profile") &&
                    subject.isInGroup("users")) {
                  return polkit.Result.YES;
              }
          });
        '';
      };
    }
     

なお上記のコードは、 NixOS で拡張セッションモードを有効にするだけ のコードなので、 実際には ~/.xsession で Window Manager や Desktop Environment の Session を起動するshellscript が必要になります。

そのため、私は ~/.xsession から次の設定で書き出したスクリプトを実行することによって、 拡張セッション接続時 に Xorg 上の Window Manager (bspwm) を起動しています:

 { config, pkgs, ... }:
    let
      bspwmInit = pkgs.writeScript "bspwmrc" ''
        #!/bin/sh
     
        ${pkgs.gnome3.dconf.lib}/libexec/dconf-service &
        ${pkgs.gnome2.GConf}/libexec/gconfd-2 &
     
        ${config.i18n.inputMethod.package}/bin/ibus-daemon -drx --config=${config.i18n.inputMethod.package}/libexec/ibus-gconf
     
        exec /etc/nixos/dotfiles/nyarla/bspwm/bspwmrc
      '';
    in
    {
      services.xserver = {
        desktopManager.xterm.enable = false;
        windowManager = {
          bspwm = {
            enable      = true;
            configFile  = "${bspwmInit}";
            sxhkd.configFile = "/etc/nixos/dotfiles/nyarla/sxhkd/sxhkdrc";
          };
        };
      };
     
      environment.etc."X11/XLaunchXRDP" = {
        mode = "0755";
        text = ''
          #!/bin/sh
     
          export _JAVA_AWT_WM_NONREPARENTING=1
     
          ${pkgs.xorg.xsetroot}/bin/xsetroot -solid "#242424" -cursor_name left_ptr
     
          SXHKD_SHELL=/bin/sh ${config.services.xserver.windowManager.bspwm.sxhkd.package}/bin/sxhkd -c /etc/nixos/dotfiles/nyarla/sxhkd/sxhkdrc &
          exec ${config.services.xserver.windowManager.bspwm.package}/bin/bspwm -c "${bspwmInit}"
        '';
      };
     
      environment.systemPackages = with pkgs; [
        polybar xtitle psmisc
      ];
    }
     

以上

今回、こう言う環境を作った際にハマった事としては、

XorgWindow Manager をどう起動させるか

と言う辺りで、これに苦戦してまるっと一日ぐらいは作業時間を取られました。 とは言え、Xorg で Window Manager さえ起動出来てしまえば後は普通に Xorg のデスクトップ環境の設定の話になるので、 その辺りはまぁ各自お好みで調整すると良いと思います。

あと NixOS はこう言った

細々とした設定を調整して適用する

という事に対して 凄く向いているLinux Distribution なので、 こう言うシステム周りを触っている時に起こしがちな、

システムの設定ファイルを弄くりまわした挙句に boot しなくなって再インストール……

と言う事が非常に起きにくく、 システム環境を良く触って変える人 には 大変オススメできる Linux Distro である と個人的には思っています。はい