@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 660 lines 25 kB view raw
1@title Diffusion User Guide: Repository Hosting 2@group userguide 3 4Guide to configuring Phorge repository hosting. 5 6Overview 7======== 8 9Phorge can host repositories and provide authenticated read and write 10access to them over HTTP and SSH. This document describes how to configure 11repository hosting. 12 13Understanding Supported Protocols 14================================= 15 16Phorge supports hosting over these protocols: 17 18| VCS | SSH | HTTP | 19|-----|-----|------| 20| Git | Supported | Supported | 21| Mercurial | Supported | Supported | 22| Subversion | Supported | Not Supported | 23 24All supported protocols handle reads (pull/checkout/clone) and writes 25(push/commit). Of the two protocols, SSH is generally more robust, secure and 26performant, but HTTP is easier to set up and supports anonymous access. 27 28| | SSH | HTTP | 29| |-----|------| 30| Reads | Yes | Yes | 31| Writes | Yes | Yes | 32| Authenticated Access | Yes | Yes | 33| Push Logs | Yes | Yes | 34| Commit Hooks | Yes | Yes | 35| Anonymous Access | No | Yes | 36| Security | Better (Asymmetric Key) | Okay (Password) | 37| Performance | Better | Okay | 38| Setup | Hard | Easy | 39 40Each repository can be configured individually, and you can use either 41protocol, or both, or a mixture across different repositories. 42 43SSH is recommended unless you need anonymous access, or are not able to 44configure it for technical reasons. 45 46 47Creating System User Accounts 48============================= 49 50Phorge uses two system user accounts, plus a third account if you 51configure SSH access. This section will guide you through creating and 52configuring them. These are system user accounts on the machine Phorge 53runs on, not Phorge user accounts. 54 55The system accounts Phorge uses are: 56 57 - The user the webserver runs as. We'll call this `www-user`. 58 - The user the daemons run as. We'll call this `daemon-user`. This 59 user is the only user which will interact with the repositories directly. 60 Other accounts will `sudo` to this account in order to perform repository 61 operations. 62 - The user that humans will connect over SSH as. We'll call this `vcs-user`. 63 If you do not plan to make repositories available over SSH, you do not need 64 to create or configure this user. 65 66IMPORTANT: As a general service management philosophy, service users are 67virtually always named after the service they are for. You are **strongly** 68encouraged to pick something other than `daemon-user` for running the daemons. A 69good username might be `phd`. 70 71To create these users: 72 73 - Create a `www-user` if one does not already exist. In most cases, this 74 user will already exist and you just need to identify which user it is. Run 75 your webserver as this user. 76 - Create a `daemon-user` if one does not already exist (you can call this user 77 whatever you want, or use an existing account). Below, you'll configure 78 the daemons to start as this user. 79 - Create a `vcs-user` if one does not already exist and you plan to set up 80 SSH. When users clone repositories, they will use a URI like 81 `vcs-user@phorge.yourcompany.com`, so common names for this user are 82 `git` or `hg`. 83 84Continue below to configure these accounts. 85 86 87Configuring Phorge 88======================= 89 90Now that you have created or identified these accounts, update the Phorge 91configuration to specify them. 92 93First, set `phd.user` to the `daemon-user`: 94 95``` 96phorge/ $ ./bin/config set phd.user daemon-user 97``` 98 99Restart the daemons to make sure this configuration works properly. They should 100start as the correct user automatically. 101 102If you're using a `vcs-user` for SSH, you should also configure that: 103 104``` 105phorge/ $ ./bin/config set diffusion.ssh-user vcs-user 106``` 107 108Next, you'll set up `sudo` permissions so these users can interact with one 109another. 110 111 112Configuring Sudo 113================ 114 115The `www-user` and `vcs-user` need to be able to `sudo` as the `daemon-user` 116so they can interact with repositories. 117 118To grant them access, edit the `sudo` system configuration. On many systems, 119you will do this by modifying the `/etc/sudoers` file using `visudo` or 120`sudoedit`. In some cases, you may add a new file to `/etc/sudoers.d` instead. 121 122To give a user account `sudo` access to run a list of binaries, add a line like 123this to the configuration file (this example would grant `vcs-user` permission 124to run `ls` as `daemon-user`): 125 126``` 127vcs-user ALL=(daemon-user) SETENV: NOPASSWD: /path/to/bin/ls 128``` 129 130The `www-user` needs to be able to run these binaries as the `daemon-user`: 131 132 - `git` (if using Git) 133 - `git-http-backend` (if using Git) 134 - `hg` (if using Mercurial) 135 - `ssh` (if configuring clusters) 136 137If you plan to use SSH, the `vcs-user` needs to be able to run these binaries 138as the `daemon-user`: 139 140 - `git` (if using Git) 141 - `git-upload-pack` (if using Git) 142 - `git-receive-pack` (if using Git) 143 - `hg` (if using Mercurial) 144 - `svnserve` (if using Subversion) 145 - `ssh` (if configuring clusters) 146 147Identify the full paths to all of these binaries on your system and add the 148appropriate permissions to the `sudo` configuration. 149 150Normally, you'll add two lines that look something like this: 151 152``` 153www-user ALL=(daemon-user) SETENV: NOPASSWD: /path/to/x, /path/to/y, ... 154vcs-user ALL=(daemon-user) SETENV: NOPASSWD: /path/to/x, /path/to/y, ... 155``` 156 157This is just a template. In the real configuration file, you need to: 158 159 - Replace `www-user`, `daemon-user` and `vcs-user` with the correct 160 usernames for your system. 161 - List every binary that these users need access to, as described above. 162 - Make sure each binary path is the full path to the correct binary location 163 on your system. 164 165Before continuing, look for this line in your `sudo` configuration: 166 167 Defaults requiretty 168 169If it's present, comment it out by putting a `#` at the beginning of the line. 170With this option enabled, VCS SSH sessions won't be able to use `sudo`. 171 172 173Additional SSH User Configuration 174================================= 175 176If you're planning to use SSH, you should also edit `/etc/passwd` and 177`/etc/shadow` to make sure the `vcs-user` account is set up correctly. 178 179**`/etc/shadow`**: Open `/etc/shadow` and find the line for the `vcs-user` 180account. 181 182The second field (which is the password field) must not be set to `!!`. This 183value will prevent login. 184 185If you have `usermod` on your system, you can adjust this value with: 186 187``` 188$ sudo usermod -p NP vcs-user 189``` 190 191If you do not have `usermod`, carefully edit the file and set the field value 192to `NP` ("no password") instead of `!!`. 193 194**`/etc/passwd`**: Open `/etc/passwd` and find the line for the `vcs-user` 195account. 196 197The last field (which is the login shell) must be set to a real shell. If it is 198set to something like `/bin/false`, then `sshd` will not be able to execute 199commands. 200 201If you have `usermod` on your system, you can adjust this value with: 202 203``` 204$ sudo usermod -s /bin/sh vcs-user 205``` 206 207If you do not have `usermod`, carefully edit the file and change the field 208to point at a real shell, usually `/bin/sh`. 209 210 211Configuring HTTP 212================ 213 214If you plan to serve repositories over authenticated HTTP, you need to set 215`diffusion.allow-http-auth` in Config. If you don't plan to serve repositories 216over HTTP (or plan to use only anonymous HTTP) you can leave this setting 217disabled. 218 219If you plan to use authenticated HTTP, you (and all other users) also need to 220configure a VCS password for your account in {nav Settings > VCS Password}. 221 222Your VCS password must be a different password than your main Phorge 223password because VCS passwords are very easy to accidentally disclose. They are 224often stored in plaintext in world-readable files, observable in `ps` output, 225and present in command output and logs. We strongly encourage you to use SSH 226instead of HTTP to authenticate access to repositories. 227 228Otherwise, if you've configured system accounts above, you're all set. No 229additional server configuration is required to make HTTP work. You should now 230be able to fetch and push repositories over HTTP. See "Cloning a Repository" 231below for more details. 232 233If you're having trouble, see "Troubleshooting HTTP" below. 234 235 236Configuring SSH 237=============== 238 239SSH access requires some additional setup. You will configure and run a second, 240restricted copy of `sshd` on the machine, on a different port from the standard 241`sshd`. This special copy of `sshd` will serve repository requests and provide 242other Phorge SSH services. 243 244NOTE: The Phorge `sshd` service **MUST** be 6.2 or newer, because 245Phorge relies on the `AuthorizedKeysCommand` option. 246 247Before continuing, you must choose a strategy for which port each copy of 248`sshd` will run on. The next section lays out various approaches. 249 250 251SSHD Port Assignment 252==================== 253 254The normal `sshd` that lets you administrate the host and the special `sshd` 255which serves repositories can't run on the same port. In particular, only one 256of them can run on port `22`, which will make it a bit inconvenient to access 257the other one. 258 259These instructions will walk you through configuring the alternate `sshd` on 260port `2222`. This is easy to configure, but if you run the service on this port 261users will clone and push to URIs like `ssh://git@host.com:2222/`, which is a 262little ugly. 263 264There are several different approaches you can use to mitigate or eliminate 265this problem. 266 267**Run on Port 2222**: You can do nothing, and just run the repository `sshd` on 268port `2222` and accept the explicit port in the URIs. This is the simplest 269approach, and you can always start here and clean things up later if you grow 270tired of dealing with the port number. 271 272**Use a Load Balancer**: You can configure a load balancer in front of the host 273and have it forward TCP traffic on port `22` to port `2222`. Then users can 274clone from `ssh://git@host.com/` without an explicit port number and you don't 275need to do anything else. 276 277This may be very easy to set up, particularly if you are hosted in AWS, and 278is often the simplest and cleanest approach. 279 280**Swap Ports**: You can move the administrative `sshd` to a new port, then run 281Phorge `sshd` on port 22. This is somewhat complicated and can be a bit 282risky if you make a mistake. See "Moving the sshd Port" below for help. 283 284**Change Client Config**: You can run on a nonstandard port, but configure SSH 285on the client side so that `ssh` automatically defaults to the correct port 286when connecting to the host. To do this, add a section like this to your 287`~/.ssh/config`: 288 289``` 290Host phorge.corporation.com 291 Port 2222 292``` 293 294(If you want, you can also add a default `User`.) 295 296Command line tools like `ssh`, `git` and `hg` will now default to port 297`2222` when connecting to this host. 298 299A downside to this approach is that your users will each need to set up their 300`~/.ssh/config` files individually. 301 302This file also allows you to define short names for hosts using the `Host` and 303`HostName` options. If you choose to do this, be aware that Phorge uses 304remote/clone URIs to figure out which repository it is operating in, but can 305not resolve host aliases defined in your `ssh` config. If you create host 306aliases they may break some features related to repository identification. 307 308If you use this approach, you will also need to specify a port explicitly when 309connecting to administrate the host. Any unit tests or other build automation 310will also need to be configured or use explicit port numbers. 311 312**Port Multiplexing**: If you have hardware access, you can power down the host 313and find the network I/O pins on the motherboard (for onboard networking) or 314network card. 315 316Carefully strip and solder a short piece of copper wire between the pins for 317the external interface `22` and internal `2222`, so the external interface can 318receive traffic for both services. 319 320(Make sure not to desolder the existing connection between external `22` and 321internal `22` or you won't be able to connect normally to administrate the 322host.) 323 324The obvious downside to this approach is that it requires physical access to 325the machine, so it won't work if you're hosted on a cloud provider. 326 327 328SSHD Setup 329========== 330 331Now that you've decided how you'll handle port assignment, you're ready to 332continue `sshd` setup. 333 334If you plan to connect to a port other than `22`, you should set this port 335as `diffusion.ssh-port` in your Phorge config: 336 337``` 338$ ./bin/config set diffusion.ssh-port 2222 339``` 340 341This port is not special, and you are free to choose a different port, provided 342you make the appropriate configuration adjustment below. 343 344**Configure and Start Phorge SSHD**: Now, you'll configure and start a 345copy of `sshd` which will serve Phorge services, including repositories, 346over SSH. 347 348This instance will use a special locked-down configuration that uses 349Phorge to handle authentication and command execution. 350 351There are three major steps: 352 353 - Create a `phorge-ssh-hook.sh` file. 354 - Create a `sshd_phorge config file. 355 - Start a copy of `sshd` using the new configuration. 356 357**Create `phorge-ssh-hook.sh`**: Copy the template in 358`phorge/resources/sshd/phorge-ssh-hook.sh` to somewhere like 359`/usr/libexec/phorge-ssh-hook.sh` and edit it to have the correct 360settings. 361 362Both the script itself **and** the parent directory the script resides in must 363be owned by `root`, and the script must have `755` permissions: 364 365``` 366$ sudo chown root /path/to/somewhere/ 367$ sudo chown root /path/to/somewhere/phorge-ssh-hook.sh 368$ sudo chmod 755 /path/to/somewhere/phorge-ssh-hook.sh 369``` 370 371If you don't do this, `sshd` will refuse to execute the hook. 372 373**Create `sshd_config` for Phorge**: Copy the template in 374`phorge/resources/sshd/sshd_config.phorge.example` to somewhere like 375`/etc/ssh/sshd_config.phorge`. 376 377Open the file and edit the `AuthorizedKeysCommand`, 378`AuthorizedKeysCommandUser`, and `AllowUsers` settings to be correct for your 379system. 380 381This configuration file also specifies the `Port` the service should run on. 382If you intend to run on a non-default port, adjust it now. 383 384**Start SSHD**: Now, start the Phorge `sshd`: 385 386 sudo /path/to/sshd -f /path/to/sshd_config.phorge 387 388If you did everything correctly, you should be able to run this command: 389 390``` 391$ echo {} | ssh vcs-user@phorge.yourcompany.com conduit conduit.ping -- 392``` 393 394...and get a response like this: 395 396```lang=json 397{"result":"phorge.yourcompany.com","error_code":null,"error_info":null} 398``` 399 400If you get an authentication error, make sure you added your public key in 401{nav Settings > SSH Public Keys}. If you're having trouble, check the 402troubleshooting section below. 403 404Authentication Over SSH 405======================= 406 407To authenticate over SSH, users should add their public keys under 408{nav Settings > SSH Public Keys}. 409 410 411Cloning a Repository 412==================== 413 414If you've already set up a hosted repository, you can try cloning it now. To 415do this, browse to the repository's main screen in Diffusion. You should see 416clone commands at the top of the page. 417 418To clone the repository, just run the appropriate command. 419 420If you don't see the commands or running them doesn't work, see below for tips 421on troubleshooting. 422 423 424Troubleshooting HTTP 425==================== 426 427Some general tips for troubleshooting problems with HTTP: 428 429 - Make sure `diffusion.allow-http-auth` is enabled in your Phorge config. 430 - Make sure HTTP serving is enabled for the repository you're trying to 431 clone. You can find this in {nav Edit Repository > Hosting}. 432 - Make sure you've configured a VCS password. This is separate from your main 433 account password. You can configure this in {nav Settings > VCS Password}. 434 - Make sure the main repository screen in Diffusion shows a clone/checkout 435 command for HTTP. If it doesn't, something above isn't set up correctly: 436 double-check your configuration. You should see a `svn checkout http://...`, 437 `git clone http://...` or `hg clone http://...` command. Run that command 438 verbatim to clone the repository. 439 440If you're using Git, using `GIT_CURL_VERBOSE` may help assess login failures. 441To do so, specify it on the command line before the `git clone` command, like 442this: 443 444 $ GIT_CURL_VERBOSE=1 git clone ... 445 446This will make `git` print out a lot more information. Particularly, the line 447with the HTTP response is likely to be useful: 448 449 < HTTP/1.1 403 Invalid credentials. 450 451In many cases, this can give you more information about what's wrong. 452 453Troubleshooting SSH 454=================== 455 456Some general tips for troubleshooting problems with SSH: 457 458 - Check that you've configured `diffusion.ssh-user`. 459 - Check that you've configured `phd.user`. 460 - Make sure SSH serving is enabled for the repository you're trying to clone. 461 You can change this setting from a main repository screen in Diffusion by 462 {nav Edit Repository > 463 Edit Hosting > 464 Host Repository on Phabricator > 465 Save and Continue > 466 SSH Read Only or Read/Write > 467 Save Changes}. 468 - Make sure you've added an SSH public key to your account. You can do this 469 in {nav Settings > SSH Public Keys}. 470 - Make sure the main repository screen in Diffusion shows a clone/checkout 471 command for SSH. If it doesn't, something above isn't set up correctly. 472 You should see an `svn checkout svn+ssh://...`, `git clone ssh://...` or 473 `hg clone ssh://...` command. Run that command verbatim to clone the 474 repository. 475 - Check your `phorge-ssh-hook.sh` file for proper settings. 476 - Check your `sshd_config.phorge` file for proper settings. 477 478To troubleshoot SSH setup: connect to the server with `ssh`, without running a 479command. You may need to use the `-T` flag, and will need to use `-p` if you 480are running on a nonstandard port. You should see a message like this one: 481 482 $ ssh -T -p 2222 vcs-user@phorge.yourcompany.com 483 phorge-ssh-exec: Welcome to Phorge. 484 485 You are logged in as alincoln. 486 487 You haven't specified a command to run. This means you're requesting an 488 interactive shell, but Phorge does not provide an interactive shell over 489 SSH. 490 491 Usually, you should run a command like `git clone` or `hg push` rather than 492 connecting directly with SSH. 493 494 Supported commands are: conduit, git-receive-pack, git-upload-pack, hg, 495 svnserve. 496 497If you see this message, all your SSH stuff is configured correctly. **If you 498get a login shell instead, you've missed some major setup step: review the 499documentation above.** If you get some other sort of error, double check these 500settings: 501 502 - You're connecting as the `vcs-user`. 503 - The `vcs-user` has `NP` in `/etc/shadow`. 504 - The `vcs-user` has `/bin/sh` or some other valid shell in `/etc/passwd`. 505 - Your SSH private key is correct, and you've added the corresponding 506 public key to Phorge in the Settings panel. 507 508If you can get this far, but can't execute VCS commands like `git clone`, there 509is probably an issue with your `sudoers` configuration. Check: 510 511 - Your `sudoers` file is set up as instructed above. 512 - You've commented out `Defaults requiretty` in `sudoers`. 513 - You don't have multiple copies of the VCS binaries (like `git-upload-pack`) 514 on your system. You may have granted sudo access to one, while the VCS user 515 is trying to run a different one. 516 - You've configured `phd.user`. 517 - The `phd.user` has read and write access to the repositories. 518 519It may also be helpful to run `sshd` in debug mode: 520 521 $ /path/to/sshd -d -d -d -f /path/to/sshd_config.phorge 522 523This will run it in the foreground and emit a large amount of debugging 524information when you connect to it. 525 526Finally, you can usually test that `sudoers` is configured correctly by 527doing something like this: 528 529 $ su vcs-user 530 $ sudo -E -n -u daemon-user -- /path/to/some/vcs-binary --help 531 532That will try to run the binary via `sudo` in a manner similar to the way that 533Phorge will run it. This can give you better error messages about issues 534with `sudoers` configuration. 535 536 537Miscellaneous Troubleshooting 538============================= 539 540 - If you're getting an error about `svnlook` not being found, add the path 541 where `svnlook` is located to the Phorge configuration 542 `environment.append-paths` (even if it already appears in PATH). This issue 543 is caused by SVN wiping the environment (including PATH) when invoking 544 commit hooks. 545 546 547Moving the sshd Port 548==================== 549 550If you want to move the standard (administrative) `sshd` to a different port to 551make Phorge repository URIs cleaner, this section has some tips. 552 553This is optional, and it is normally easier to do this by putting a load 554balancer in front of Phorge and having it accept TCP traffic on port 22 555and forward it to some other port. 556 557When moving `sshd`, be careful when editing the configuration. If you get it 558wrong, you may lock yourself out of the machine. Restarting `sshd` generally 559will not interrupt existing connections, but you should exercise caution. Two 560strategies you can use to mitigate this risk are: smoke-test configuration by 561starting a second `sshd`; and use a `screen` session which automatically 562repairs configuration unless stopped. 563 564To smoke-test a configuration, just start another `sshd` using the `-f` flag: 565 566 sudo /path/to/sshd -f /path/to/config_file.edited 567 568You can then connect and make sure the edited config file is valid before 569replacing your primary configuration file. 570 571To automatically repair configuration, start a `screen` session with a command 572like this in it: 573 574 sleep 60 ; mv sshd_config.good sshd_config ; /etc/init.d/sshd restart 575 576The specific command may vary for your system, but the general idea is to have 577the machine automatically restore configuration after some period of time if 578you don't stop it. If you lock yourself out, this can fix things automatically. 579 580Now that you're ready to edit your configuration, open up your `sshd` config 581(often `/etc/ssh/sshd_config`) and change the `Port` setting to some other port, 582like `222` (you can choose any port other than 22). 583 584 Port 222 585 586Very carefully, restart `sshd`. Verify that you can connect on the new port: 587 588 ssh -p 222 ... 589 590Now you can move the Phorge `sshd` to port 22, then adjust the value 591for `diffusion.ssh-port` in your Phorge configuration. 592 593You can set up and enable this systemd unit to start the second sshd 594daemon on every reboot: 595 596``` 597name=/etc/systemd/system/phorge-ssh.service,lang=ini 598[Unit] 599Description=Phorge sshd 600Documentation=https://we.phorge.it/book/phorge/article/diffusion_hosting/#sshd-setup 601After=network.target auditd.service 602 603[Service] 604ExecStartPre=/usr/sbin/sshd -t -f /path/to/config_file.edited 605ExecStart=/usr/sbin/sshd -f /path/to/config_file.edited 606ExecReload=/usr/sbin/sshd -t -f /path/to/config_file.edited 607ExecReload=/bin/kill -HUP $MAINPID 608KillMode=process 609Restart=on-failure 610RestartPreventExitStatus=255 611Type=notify 612RuntimeDirectory=sshd 613RuntimeDirectoryMode=0755 614 615[Install] 616WantedBy=multi-user.target 617Alias=phorge-sshd.service 618``` 619 620No Direct Pushes 621================ 622 623You may get an error about "No Direct Pushes" when trying to push. This means 624you are pushing directly to the repository instead of pushing through 625Phorge. This is not supported: writes to hosted repositories must go 626through Phorge so it can perform authentication, enforce permissions, 627write logs, proxy requests, apply rewriting, etc. 628 629One way to do a direct push by mistake is to use a `file:///` URI to interact 630with the repository from the same machine. This is not supported. Instead, use 631one of the repository URIs provided in the web interface, even if you're 632working on the same machine. 633 634Another way to do a direct push is to misconfigure SSH (or not configure it at 635all) so that none of the logic described above runs and you just connect 636normally as a system user. In this case, the `ssh` test described above will 637fail (you'll get a command prompt when you connect, instead of the message you 638are supposed to get, as described above). 639 640If you encounter this error: make sure you're using a remote URI given to 641you by Diffusion in the web interface, then run through the troubleshooting 642steps above carefully. 643 644Sometimes users encounter this problem because they skip this whole document 645assuming they don't need to configure anything. This will not work, and you 646MUST configure things as described above for hosted repositories to work. 647 648The technical reason this error occurs is that the `PHABRICATOR_USER` variable 649is not defined in the environment when commit hooks run. This variable is set 650by Phorge when a request passes through the authentication layer that this 651document provides instructions for configuring. Its absence indicates that the 652request did not pass through Phorge. 653 654 655Next Steps 656========== 657 658Once hosted repositories are set up: 659 660 - learn about commit hooks with @{article:Diffusion User Guide: Commit Hooks}.