1{ config, lib, pkgs, ... }:
2with lib;
3let
4 gce = pkgs.google-compute-engine;
5in
6{
7 imports = [
8 ../profiles/headless.nix
9 ../profiles/qemu-guest.nix
10 ];
11
12
13 fileSystems."/" = {
14 fsType = "ext4";
15 device = "/dev/disk/by-label/nixos";
16 autoResize = true;
17 };
18
19 boot.growPartition = true;
20 boot.kernelParams = [ "console=ttyS0" "panic=1" "boot.panic_on_fail" ];
21 boot.initrd.kernelModules = [ "virtio_scsi" ];
22 boot.kernelModules = [ "virtio_pci" "virtio_net" ];
23
24 # Generate a GRUB menu.
25 boot.loader.grub.device = "/dev/sda";
26 boot.loader.timeout = 0;
27
28 # Don't put old configurations in the GRUB menu. The user has no
29 # way to select them anyway.
30 boot.loader.grub.configurationLimit = 0;
31
32 # Allow root logins only using SSH keys
33 # and disable password authentication in general
34 services.openssh.enable = true;
35 services.openssh.permitRootLogin = "prohibit-password";
36 services.openssh.passwordAuthentication = mkDefault false;
37
38 # enable OS Login. This also requires setting enable-oslogin=TRUE metadata on
39 # instance or project level
40 security.googleOsLogin.enable = true;
41
42 # Use GCE udev rules for dynamic disk volumes
43 services.udev.packages = [ gce ];
44
45 # Force getting the hostname from Google Compute.
46 networking.hostName = mkDefault "";
47
48 # Always include cryptsetup so that NixOps can use it.
49 environment.systemPackages = [ pkgs.cryptsetup ];
50
51 # Make sure GCE image does not replace host key that NixOps sets
52 environment.etc."default/instance_configs.cfg".text = lib.mkDefault ''
53 [InstanceSetup]
54 set_host_keys = false
55 '';
56
57 # Rely on GCP's firewall instead
58 networking.firewall.enable = mkDefault false;
59
60 # Configure default metadata hostnames
61 networking.extraHosts = ''
62 169.254.169.254 metadata.google.internal metadata
63 '';
64
65 networking.timeServers = [ "metadata.google.internal" ];
66
67 networking.usePredictableInterfaceNames = false;
68
69 # GC has 1460 MTU
70 networking.interfaces.eth0.mtu = 1460;
71
72 # Used by NixOps
73 systemd.services.fetch-instance-ssh-keys = {
74 description = "Fetch host keys and authorized_keys for root user";
75
76 wantedBy = [ "sshd.service" ];
77 before = [ "sshd.service" ];
78 after = [ "network-online.target" ];
79 wants = [ "network-online.target" ];
80 path = [ pkgs.wget ];
81
82 serviceConfig = {
83 Type = "oneshot";
84 ExecStart = pkgs.runCommand "fetch-instance-ssh-keys" { } ''
85 cp ${./fetch-instance-ssh-keys.bash} $out
86 chmod +x $out
87 ${pkgs.shfmt}/bin/shfmt -i 4 -d $out
88 ${pkgs.shellcheck}/bin/shellcheck $out
89 patchShebangs $out
90 '';
91 PrivateTmp = true;
92 StandardError = "journal+console";
93 StandardOutput = "journal+console";
94 };
95 };
96
97 systemd.services.google-instance-setup = {
98 description = "Google Compute Engine Instance Setup";
99 after = [ "network-online.target" "network.target" "rsyslog.service" ];
100 before = [ "sshd.service" ];
101 path = with pkgs; [ coreutils ethtool openssh ];
102 serviceConfig = {
103 ExecStart = "${gce}/bin/google_instance_setup";
104 StandardOutput="journal+console";
105 Type = "oneshot";
106 };
107 wantedBy = [ "sshd.service" "multi-user.target" ];
108 };
109
110 systemd.services.google-network-daemon = {
111 description = "Google Compute Engine Network Daemon";
112 after = [ "network-online.target" "network.target" "google-instance-setup.service" ];
113 path = with pkgs; [ iproute2 ];
114 serviceConfig = {
115 ExecStart = "${gce}/bin/google_network_daemon";
116 StandardOutput="journal+console";
117 Type="simple";
118 };
119 wantedBy = [ "multi-user.target" ];
120 };
121
122 systemd.services.google-clock-skew-daemon = {
123 description = "Google Compute Engine Clock Skew Daemon";
124 after = [ "network.target" "google-instance-setup.service" "google-network-daemon.service" ];
125 serviceConfig = {
126 ExecStart = "${gce}/bin/google_clock_skew_daemon";
127 StandardOutput="journal+console";
128 Type = "simple";
129 };
130 wantedBy = ["multi-user.target"];
131 };
132
133
134 systemd.services.google-shutdown-scripts = {
135 description = "Google Compute Engine Shutdown Scripts";
136 after = [
137 "network-online.target"
138 "network.target"
139 "rsyslog.service"
140 "google-instance-setup.service"
141 "google-network-daemon.service"
142 ];
143 serviceConfig = {
144 ExecStart = "${pkgs.coreutils}/bin/true";
145 ExecStop = "${gce}/bin/google_metadata_script_runner --script-type shutdown";
146 RemainAfterExit = true;
147 StandardOutput="journal+console";
148 TimeoutStopSec = "0";
149 Type = "oneshot";
150 };
151 wantedBy = [ "multi-user.target" ];
152 };
153
154 systemd.services.google-startup-scripts = {
155 description = "Google Compute Engine Startup Scripts";
156 after = [
157 "network-online.target"
158 "network.target"
159 "rsyslog.service"
160 "google-instance-setup.service"
161 "google-network-daemon.service"
162 ];
163 serviceConfig = {
164 ExecStart = "${gce}/bin/google_metadata_script_runner --script-type startup";
165 KillMode = "process";
166 StandardOutput = "journal+console";
167 Type = "oneshot";
168 };
169 wantedBy = [ "multi-user.target" ];
170 };
171
172 environment.etc."sysctl.d/11-gce-network-security.conf".source = "${gce}/sysctl.d/11-gce-network-security.conf";
173}