https://wiki.archlinux.org/api.php?action=feedcontributions&user=Chehri&feedformat=atomArchWiki - User contributions [en]2024-03-29T10:19:08ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=NFS&diff=474275NFS2017-04-15T20:05:04Z<p>Chehri: Typo fix.</p>
<hr />
<div>[[Category:File systems]]<br />
[[Category:Network sharing]]<br />
[[ar:NFS]]<br />
[[cs:NFS]]<br />
[[de:Network File System]]<br />
[[es:NFS]]<br />
[[fr:NFS]]<br />
[[it:NFS]]<br />
[[ja:NFS]]<br />
[[ru:NFS]]<br />
[[zh-hans:NFS]]<br />
{{Related articles start}}<br />
{{Related|NFS/Troubleshooting}}<br />
{{Related articles end}}<br />
From [[Wikipedia: Network File System|Wikipedia]]: <br />
: ''Network File System (NFS) is a distributed file system protocol originally developed by Sun Microsystems in 1984, allowing a user on a client computer to access files over a network in a manner similar to how local storage is accessed.''<br />
<br />
{{Note| NFS is not encrypted. Tunnel NFS through an encrypted protocol like [[Kerberos]], or [[tinc]] when dealing with sensitive data.}}<br />
<br />
== Installation ==<br />
<br />
Both client and server only require the [[install|installation]] of the {{Pkg|nfs-utils}} package.<br />
<br />
It is '''highly''' recommended to use a [[Time#Time synchronization|time sync daemon]] to keep client/server clocks in sync. Without accurate clocks on all nodes, NFS can introduce unwanted delays.<br />
<br />
==Configuration==<br />
<br />
===Server===<br />
<br />
NFS needs to see the list of shares (referred to as "exports" from here on out), which are defined in {{ic|/etc/exports}} in order to serve-up the content. The NFS root directory can be any directory on the file system. In the interest of security, it is recommended to use an NFS export root which will keep users limited to that mount point only. The following example illustrates this concept.<br />
<br />
Any NFS shares defined in {{ic|/etc/exports}} are relative to the NFS root. In this example, the NFS root will be {{ic|/srv/nfs}} and we are sharing {{ic|/mnt/music}}.<br />
<br />
# mkdir -p /srv/nfs/music /mnt/music<br />
<br />
Read/Write permissions must be set on the music directory so clients may write to it. <br />
<br />
Now mount the actual target share, {{ic|/mnt/music}} to the directory under the NFS root via the mount --bind command:<br />
<br />
# mount --bind /mnt/music /srv/nfs/music<br />
<br />
To make it stick across server reboots, add the bind mount to {{ic|fstab}}:<br />
<br />
{{hc|/etc/fstab|<br />
/mnt/music /srv/nfs/music none bind 0 0<br />
}}<br />
<br />
{{Note|[[ZFS]] filesystems require special handling of bindmounts, see [[ZFS#Bind mount]].}}<br />
<br />
Add directories to be shared and an ip address or hostname(s) of client machines that will be allowed to mount them in {{ic|exports}}:<br />
<br />
{{hc|/etc/exports|<nowiki><br />
/srv/nfs 192.168.1.0/24(rw,fsid=root,no_subtree_check)<br />
/srv/nfs/music 192.168.1.0/24(rw,no_subtree_check,nohide) # note the nohide option which is applied to mounted directories on the file system.<br />
</nowiki>}}<br />
<br />
{{Note|If the target export is a tmpfs filesystem, the {{ic|1=fsid=1}} option is required.}}<br />
<br />
Users need-not open the share to the entire subnet; one can specify a single IP address or hostname as well.<br />
<br />
For more information about all available options see {{man|5|exports}}.<br />
<br />
{{Note|Modifying {{ic|/etc/exports}} while the server is running will require a re-export for changes to take effect as noted by the upstream comments in {{ic|/etc/exports}}:<br />
<br />
# exportfs -rav<br />
<br />
}}<br />
<br />
==== Starting the server ====<br />
<br />
[[Start]] and [[enable]] {{ic|nfs-server.service}}.<br />
<br />
==== Miscellaneous ====<br />
<br />
===== Optional configuration =====<br />
<br />
Advanced configuration options can be set in {{ic|/etc/nfs.conf}}. Users setting up a simple configuration may not need to edit this file.<br />
<br />
===== Restricting NFS to interfaces/IPs =====<br />
<br />
By default, starting {{ic|nfs-server.service}} will listen for connections on all network interfaces, regardless of {{ic|/etc/exports}}. This can be changed by defining which IPs and/or hostnames to listen on.<br />
<br />
{{hc|/etc/nfs.conf|2=<br />
[nfsd]<br />
host=192.168.1.123<br />
# Alternatively, you can use your hostname.<br />
# host=myhostname<br />
}}<br />
<br />
Restarting the service will apply the changes immediately. <br />
<br />
# systemctl restart nfs-server.service<br />
<br />
===== Ensure NFSv4 idmapping is fully enabled =====<br />
<br />
Even though idmapd may be running, it may not be fully enabled. Verify by checking {{ic|cat /sys/module/nfsd/parameters/nfs4_disable_idmapping}} returns {{ic|N}}. If not:<br />
<br />
# echo "N" | sudo tee /sys/module/nfsd/parameters/nfs4_disable_idmapping<br />
<br />
Set this to survive reboots by adding an option to the nfs kernel module:<br />
<br />
# echo "options nfs nfs4_disable_idmapping=0" | sudo tee -a /etc/modprobe.d/nfs.conf<br />
<br />
(See [https://bbs.archlinux.org/viewtopic.php?pid=1530693#p1530693 this forum reply] for more information.)<br />
<br />
If journalctl reports lines like the following when starting nfs-server.service and nfs-idmapd.service, then this may be the solution.<br />
<br />
rpc.idmapd[25010]: nfsdcb: authbuf=192.168.0.0/16 authtype=user<br />
rpc.idmapd[25010]: nfsdcb: bad name in upcall<br />
<br />
===== Static ports for NFSv3 =====<br />
{{Out of date|Configuration should be done in /etc/nfs.conf since {{Pkg|nfs-utils}} 2.1.1.[https://sourceforge.net/projects/nfs/files/nfs-utils/2.1.1/]}}<br />
Users needing support for NFSv3 clients, may wish to consider using static ports. By default, for NFSv3 operation {{ic|rpc.statd}} and {{ic|lockd}} use random ephemeral ports; in order to allow NFSv3 operations through a firewall static ports need to be defined. Edit {{ic|/etc/sysconfig/nfs}} to set {{ic|STATDARGS}}:<br />
<br />
{{hc|/etc/sysconfig/nfs|2=<br />
STATDARGS="-p 32765 -o 32766 -T 32803"<br />
}}<br />
<br />
The {{ic|rpc.mountd}} should consult {{ic|/etc/services}} and bind to the same static port 20048 under normal operation; however, if it needs to be explicity defined edit {{ic|/etc/sysconfig/nfs}} to set {{ic|RPCMOUNTDARGS}}:<br />
<br />
{{hc|/etc/sysconfig/nfs|2=<br />
RPCMOUNTDARGS="-p 20048"<br />
}}<br />
<br />
After making these changes, several services need to be restarted; the first writes the configuration options out to {{ic|/run/sysconfig/nfs-utils}} (see {{ic|/usr/lib/systemd/scripts/nfs-utils_env.sh}}), the second restarts {{ic|rpc.statd}} with the new ports, the last reloads {{ic|lockd}} (kernel module) with the new ports. [[Restart]] these services now: {{ic|nfs-config}}, {{ic|rpcbind}}, {{ic|rpc-statd}}, and {{ic|nfs-server}}.<br />
<br />
After the restarts, use {{ic|rpcinfo -p}} on the server to examine the static ports are as expected. Using {{ic|rpcinfo -p <server IP>}} from the client should reveal the exact same static ports.<br />
<br />
===== NFSv2 compatibility =====<br />
{{Out of date|Configuration should be done in /etc/nfs.conf since {{Pkg|nfs-utils}} 2.1.1.[https://sourceforge.net/projects/nfs/files/nfs-utils/2.1.1/]}}<br />
Users needing to support clients using NFSv2 (for example U-Boot), should set {{ic|1=RPCNFSDARGS="-V 2"}} in {{ic|/etc/sysconfig/nfs}}.<br />
<br />
===== Firewall configuration =====<br />
<br />
To enable access through a firewall, tcp and udp ports 111, 2049, and 20048 need to be opened when using the default configuration; use {{ic|rpcinfo -p}} to examine the exact ports in use on the server. To configure this for [[iptables]], execute this commands:<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 111 -j ACCEPT<br />
# iptables -A INPUT -p tcp -m tcp --dport 2049 -j ACCEPT<br />
# iptables -A INPUT -p tcp -m tcp --dport 20048 -j ACCEPT<br />
# iptables -A INPUT -p udp -m udp --dport 111 -j ACCEPT<br />
# iptables -A INPUT -p udp -m udp --dport 2049 -j ACCEPT<br />
# iptables -A INPUT -p udp -m udp --dport 20048 -j ACCEPT<br />
<br />
To have this configuration load on every system start, edit {{ic|/etc/iptables/iptables.rules}} to include the following lines:<br />
<br />
{{hc|/etc/iptables/iptables.rules|<nowiki><br />
-A INPUT -p tcp -m tcp --dport 111 -j ACCEPT<br />
-A INPUT -p tcp -m tcp --dport 2049 -j ACCEPT<br />
-A INPUT -p tcp -m tcp --dport 20048 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 111 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 2049 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 20048 -j ACCEPT<br />
</nowiki>}}<br />
<br />
The previous commands can be saved by executing:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
{{note|This command will '''override''' the current iptables start configuration with the current iptables configuration!}}<br />
<br />
If using NFSv3 and the above listed static ports for {{ic|rpc.statd}} and {{ic|lockd}} these also need to be added to the configuration:<br />
<br />
{{hc|/etc/iptables/iptables.rules|<nowiki><br />
-A INPUT -p tcp -m tcp --dport 32765 -j ACCEPT<br />
-A INPUT -p tcp -m tcp --dport 32803 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 32765 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 32803 -j ACCEPT<br />
</nowiki>}}<br />
<br />
If using V4-only setup, only tcp port 2049 need to be opened. Therefore only one line needed.<br />
<br />
{{hc|/etc/iptables/iptables.rules|<nowiki><br />
-A INPUT -p tcp -m tcp --dport 2049 -j ACCEPT<br />
</nowiki>}}<br />
<br />
To apply changes, [[Restart]] {{ic|iptables.service}}.<br />
<br />
=== Client ===<br />
Users intending to use NFS4 with [[Kerberos]], also need to [[start]] and [[enable]] {{ic|nfs-client.target}}, which starts {{ic|rpc-gssd.service}}. However, due to bug {{Bug|50663}} in glibc, {{ic|rpc-gssd.service}} currently fails to start. Adding the "-f" (foreground) flag in the service is a workaround:<br />
<br />
{{hc|# systemctl edit rpc-gssd.service|2=<br />
[Unit]<br />
Requires=network-online.target<br />
After=network-online.target<br />
<br />
[Service]<br />
Type=simple<br />
ExecStart=<br />
ExecStart=/usr/sbin/rpc.gssd -f<br />
}}<br />
<br />
==== Error from systemd ====<br />
<br />
Users experiencing the following may consider turning off the service using system's masking feature: "Dependency failed for pNFS block layout mapping daemon."<br />
<br />
Example:<br />
<br />
# systemctl mask nfs-blkmap.service<br />
<br />
==== Manual mounting ====<br />
<br />
For NFSv3 use this command to show the server's exported file systems:<br />
<br />
$ showmount -e servername<br />
<br />
For NFSv4 mount the root NFS directory and look around for available mounts:<br />
<br />
# mount server:/ /mountpoint/on/client<br />
<br />
Then mount omitting the server's NFS export root: <br />
<br />
# mount -t nfs -o vers=4 servername:/music /mountpoint/on/client<br />
<br />
If mount fails try including the server's export root (required for Debian/RHEL/SLES, some distributions need {{ic|-t nfs4}} instead of {{ic|-t nfs}}):<br />
<br />
# mount -t nfs -o vers=4 servername:/full/path/to/music /mountpoint/on/client<br />
<br />
{{Note|Server name needs to be a valid hostname (not just IP address). Otherwise mounting of remote share will hang.}}<br />
<br />
==== Mount using /etc/fstab ====<br />
<br />
Using [[fstab]] is useful for a server which is always on, and the NFS shares are available whenever the client boots up. Edit {{ic|/etc/fstab}} file, and add an appropriate line reflecting the setup. Again, the server's NFS export root is omitted.<br />
<br />
{{hc|/etc/fstab|<nowiki><br />
servername:/music /mountpoint/on/client nfs rsize=8192,wsize=8192,timeo=14,_netdev 0 0<br />
</nowiki>}}<br />
<br />
{{Note|Consult {{man|5|nfs}} and {{man|8|mount}} for more mount options.}}<br />
<br />
Some additional mount options to consider are include:<br />
<br />
; rsize and wsize: The {{ic|rsize}} value is the number of bytes used when reading from the server. The {{ic|wsize}} value is the number of bytes used when writing to the server. The default for both is 1024, but using higher values such as 8192 can improve throughput. This is not universal. It is recommended to test after making this change, see [[#Performance tuning]].<br />
<br />
; timeo: The {{ic|timeo}} value is the amount of time, in tenths of a second, to wait before resending a transmission after an RPC timeout. After the first timeout, the timeout value is doubled for each retry for a maximum of 60 seconds or until a major timeout occurs. If connecting to a slow server or over a busy network, better performance can be achieved by increasing this timeout value. <br />
<br />
; _netdev: The {{ic|_netdev}} option tells the system to wait until the network is up before trying to mount the share. systemd assumes this for NFS, but anyway it is good practice to use it for all types of networked file systems<br />
<br />
{{Note|Setting the sixth field ({{ic|fs_passno}}) to a nonzero value may lead to unexpected behaviour, e.g. hangs when the systemd automount waits for a check which will never happen.}}<br />
<br />
==== Mount using /etc/fstab with systemd ====<br />
<br />
Another method is using the systemd {{ic|automount}} service. This is a better option than {{ic|_netdev}}, because it remounts the network device quickly when the connection is broken and restored. As well, it solves the problem from autofs, see the example below:<br />
<br />
{{hc|1=/etc/fstab|2=<br />
servername:/home ''/mountpoint/on/client'' nfs noauto,x-systemd.automount,x-systemd.device-timeout=10,timeo=14,x-systemd.idle-timeout=1min 0 0 <br />
}}<br />
<br />
One might have to reboot the client to make systemd aware of the changes to fstab. Alternatively, try [[Systemd#Using_units|reloading]] systemd and restarting {{ic|''mountpoint-on-client''.automount}} to reload the {{ic|/etc/fstab}} configuration.<br />
<br />
{{Tip|<br />
* The {{ic|noauto}} mount option will not mount the NFS share until it is accessed: use {{ic|auto}} for it to be available immediately. <br> If experiencing any issues with the mount failing due to the network not being up/available, [[enable]] {{ic|NetworkManager-wait-online.service}}. It will ensure that {{ic|network.target}} has all the links available prior to being active.<br />
* The {{ic|users}} mount option would allow user mounts, but be aware it implies further options as {{ic|noexec}} for example.<br />
* The {{ic|<nowiki>x-systemd.idle-timeout=1min</nowiki>}} option will unmount the NFS share automatically after 1 minute of non-use. Good for laptops which might suddenly disconnect from the network.<br />
* If shutdown/reboot holds too long because of NFS, [[enable]] {{ic|NetworkManager-wait-online.service}} to ensure that NetworkManager is not exited before the NFS volumes are unmounted. You may also try to add the {{ic|<nowiki>x-systemd.requires=network.target</nowiki>}} mount option if shutdown takes too long. }}<br />
<br />
{{Note|Users trying to automount a NFS-share via systemd which is mounted the same way on the server may experience a freeze when handling larger amounts of data.}}<br />
<br />
==== Mount using autofs ====<br />
<br />
Using [[autofs]] is useful when multiple machines want to connect via NFS; they could both be clients as well as servers. The reason this method is preferable over the earlier one is that if the server is switched off, the client will not throw errors about being unable to find NFS shares. See [[autofs#NFS network mounts]] for details.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Performance tuning ===<br />
<br />
In order to get the most out of NFS, it is necessary to tune the {{ic|rsize}} and {{ic|wsize}} mount options to meet the requirements of the network configuration.<br />
<br />
=== Automounting shares with systemd-networkd ===<br />
<br />
Users making use of systemd-networkd might notice nfs mounts the fstab are not mounted when booting; errors like the following are common:<br />
<br />
mount[311]: mount.nfs4: Network is unreachable<br />
<br />
The solution is simple; force systemd to wait for the network to be completely configured by [[enabling]] {{ic|systemd-networkd-wait-online.service}}. In theory this slows down the boot-process because less services run in parallel.<br />
<br />
=== Automatic mount handling ===<br />
<br />
This trick is useful for laptops that require nfs shares from a local wireless network. If the nfs host becomes unreachable, the nfs share will be unmounted to hopefully prevent system hangs when using the hard mount option. See https://bbs.archlinux.org/viewtopic.php?pid=1260240#p1260240<br />
<br />
Make sure that the NFS mount points are correctly indicated in {{ic|/etc/fstab}}:<br />
<br />
{{hc|$ cat /etc/fstab|<nowiki><br />
lithium:/mnt/data /mnt/data nfs noauto,noatime,rsize=32768,wsize=32768 0 0<br />
lithium:/var/cache/pacman /var/cache/pacman nfs noauto,noatime,rsize=32768,wsize=32768 0 0</nowiki><br />
}}<br />
<br />
{{Note|You must use hostnames in {{ic|/etc/fstab}} for this to work, not IP addresses.}}<br />
<br />
The {{ic|noauto}} mount option tells systemd not to automatically mount the shares at boot. systemd would otherwise attempt to mount the nfs shares that may or may not exist on the network causing the boot process to appear to stall on a blank screen.<br />
<br />
In order to mount NFS shares with non-root users the {{ic|user}} option has to be added. <br />
<br />
Create the {{ic|auto_share}} script that will be used by ''cron'' or ''systemd/Timers'' to use ICMP ping to check if the NFS host is reachable:<br />
<br />
{{hc|/usr/local/bin/auto_share|<nowiki><br />
#!/bin/bash<br />
<br />
function net_umount {<br />
umount -l -f $1 &>/dev/null<br />
}<br />
<br />
function net_mount {<br />
mountpoint -q $1 || mount $1<br />
}<br />
<br />
NET_MOUNTS=$(sed -e '/^.*#/d' -e '/^.*:/!d' -e 's/\t/ /g' /etc/fstab | tr -s " ")$'\n'b<br />
<br />
printf %s "$NET_MOUNTS" | while IFS= read -r line<br />
do<br />
SERVER=$(echo $line | cut -f1 -d":")<br />
MOUNT_POINT=$(echo $line | cut -f2 -d" ")<br />
<br />
# Check if server already tested<br />
if [[ "${server_ok[@]}" =~ "${SERVER}" ]]; then<br />
# The server is up, make sure the share are mounted<br />
net_mount $MOUNT_POINT<br />
elif [[ "${server_notok[@]}" =~ "${SERVER}" ]]; then<br />
# The server could not be reached, unmount the share<br />
net_umount $MOUNT_POINT<br />
else<br />
# Check if the server is reachable<br />
ping -c 1 "${SERVER}" &>/dev/null<br />
<br />
if [ $? -ne 0 ]; then<br />
server_notok[${#Unix[@]}]=$SERVER<br />
# The server could not be reached, unmount the share<br />
net_umount $MOUNT_POINT<br />
else<br />
server_ok[${#Unix[@]}]=$SERVER<br />
# The server is up, make sure the share are mounted<br />
net_mount $MOUNT_POINT<br />
fi<br />
fi<br />
done<br />
</nowiki>}}<br />
<br />
{{Note|If you want to test using a TCP probe instead of ICMP ping (default is tcp port 2049 in NFS4) then replace the line:<br />
<br />
# Check if the server is reachable<br />
ping -c 1 "${SERVER}" &>/dev/null<br />
<br />
with:<br />
<br />
# Check if the server is reachable<br />
timeout 1 bash -c ": < /dev/tcp/${SERVER}/2049"<br />
<br />
in the {{ic|auto_share}} script above.}}<br />
<br />
# chmod +x /usr/local/bin/auto_share<br />
<br />
Create a cron entry or a systemd/Timers timer to check every minute if the server of the shares are reachable.<br />
<br />
==== Cron ====<br />
<br />
{{hc|# crontab -e|<nowiki><br />
* * * * * /usr/local/bin/auto_share<br />
</nowiki>}}<br />
<br />
==== systemd/Timers ====<br />
<br />
{{hc|# /etc/systemd/system/auto_share.timer|<nowiki><br />
[Unit]<br />
Description=Check the network mounts<br />
<br />
[Timer]<br />
OnCalendar=*-*-* *:*:00<br />
<br />
[Install]<br />
WantedBy=timer.target<br />
</nowiki>}}<br />
<br />
{{hc|# /etc/systemd/system/auto_share.service|<nowiki><br />
[Unit]<br />
Description=Check the network mounts<br />
<br />
[Service]<br />
Type=simple<br />
ExecStart=/usr/local/bin/auto_share<br />
</nowiki>}}<br />
<br />
# systemctl enable auto_share.timer<br />
<br />
==== Mount at startup via systemd ====<br />
<br />
A systemd unit file can also be used to mount the NFS shares at startup. The unit file is not necessary if NetworkManager is installed and configured on the client system. See [[#NetworkManager dispatcher]].<br />
<br />
{{hc|/etc/systemd/system/auto_share.service|<nowiki><br />
[Unit]<br />
Description=NFS automount<br />
After=syslog.target network.target<br />
<br />
[Service]<br />
Type=oneshot<br />
RemainAfterExit=yes<br />
ExecStart=/usr/local/bin/auto_share<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
</nowiki>}}<br />
<br />
Now [[enable]] the {{ic|auto_share.service}}.<br />
<br />
==== NetworkManager dispatcher ====<br />
<br />
In addition to the method described previously, [[NetworkManager#Network_services_with_NetworkManager_dispatcher|NetworkManager]] can also be configured to run a script on network status change: [[Enable]] and [[start]] the {{ic|NetworkManager-dispatcher.service}}.<br />
<br />
The easiest method for mount shares on network status change is to just symlink to the {{ic|auto_share}} script:<br />
<br />
# ln -s /usr/local/bin/auto_share /etc/NetworkManager/dispatcher.d/30-nfs.sh<br />
<br />
However, in that particular case unmounting will happen only after the network connection has already been disabled, which is unclean and may result in effects like freezing of KDE Plasma applets. <br />
<br />
The following script safely unmounts the NFS shares before the relevant network connection is disabled by listening for the {{ic|pre-down}} and {{ic|vpn-pre-down}} events:<br />
<br />
{{Note|This script ignores mounts with the noauto option.}}<br />
<br />
{{hc|/etc/NetworkManager/dispatcher.d/30-nfs.sh|<nowiki><br />
#!/bin/bash<br />
<br />
# Find the connection UUID with "nmcli con show" in terminal.<br />
# All NetworkManager connection types are supported: wireless, VPN, wired...<br />
WANTED_CON_UUID="CHANGE-ME-NOW-9c7eff15-010a-4b1c-a786-9b4efa218ba9"<br />
<br />
if [[ "$CONNECTION_UUID" == "$WANTED_CON_UUID" ]]; then<br />
<br />
# Script parameter $1: NetworkManager connection name, not used<br />
# Script parameter $2: dispatched event<br />
<br />
case "$2" in<br />
"up")<br />
mount -a -t nfs4,nfs <br />
;;<br />
"pre-down");&<br />
"vpn-pre-down")<br />
umount -l -a -t nfs4,nfs >/dev/null<br />
;;<br />
esac<br />
fi<br />
</nowiki>}}<br />
<br />
Make the script executable with [[chmod]] and create a symlink inside {{ic|/etc/NetworkManager/dispatcher.d/pre-down}} to catch the {{ic|pre-down}} events:<br />
<br />
# ln -s /etc/NetworkManager/dispatcher.d/30-nfs.sh /etc/NetworkManager/dispatcher.d/pre-down.d/30-nfs.sh<br />
<br />
The above script can be modified to mount different shares (even other than NFS) for different connections.<br />
<br />
See also: [[NetworkManager#Use dispatcher to handle mounting of CIFS shares]].<br />
<br />
== Troubleshooting ==<br />
<br />
There is a dedicated article [[NFS Troubleshooting]].<br />
<br />
== See also ==<br />
<br />
* See also [[Avahi]], a Zeroconf implementation which allows automatic discovery of NFS shares.<br />
* HOWTO: [[Diskless network boot NFS root]]<br />
* [http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.prftungd/doc/prftungd/nfs_perf.htm NFS Performance Management]<br />
* [http://blogs.msdn.com/sfu/archive/2008/04/14/all-well-almost-about-client-for-nfs-configuration-and-performance.aspx Microsoft Services for Unix NFS Client info]<br />
* [https://blogs.oracle.com/jag/entry/nfs_on_snow_leopard NFS on Snow Leopard]</div>Chehrihttps://wiki.archlinux.org/index.php?title=NFS&diff=474274NFS2017-04-15T20:04:18Z<p>Chehri: Added instructions on how to set which IPs to listen on.</p>
<hr />
<div>[[Category:File systems]]<br />
[[Category:Network sharing]]<br />
[[ar:NFS]]<br />
[[cs:NFS]]<br />
[[de:Network File System]]<br />
[[es:NFS]]<br />
[[fr:NFS]]<br />
[[it:NFS]]<br />
[[ja:NFS]]<br />
[[ru:NFS]]<br />
[[zh-hans:NFS]]<br />
{{Related articles start}}<br />
{{Related|NFS/Troubleshooting}}<br />
{{Related articles end}}<br />
From [[Wikipedia: Network File System|Wikipedia]]: <br />
: ''Network File System (NFS) is a distributed file system protocol originally developed by Sun Microsystems in 1984, allowing a user on a client computer to access files over a network in a manner similar to how local storage is accessed.''<br />
<br />
{{Note| NFS is not encrypted. Tunnel NFS through an encrypted protocol like [[Kerberos]], or [[tinc]] when dealing with sensitive data.}}<br />
<br />
== Installation ==<br />
<br />
Both client and server only require the [[install|installation]] of the {{Pkg|nfs-utils}} package.<br />
<br />
It is '''highly''' recommended to use a [[Time#Time synchronization|time sync daemon]] to keep client/server clocks in sync. Without accurate clocks on all nodes, NFS can introduce unwanted delays.<br />
<br />
==Configuration==<br />
<br />
===Server===<br />
<br />
NFS needs to see the list of shares (referred to as "exports" from here on out), which are defined in {{ic|/etc/exports}} in order to serve-up the content. The NFS root directory can be any directory on the file system. In the interest of security, it is recommended to use an NFS export root which will keep users limited to that mount point only. The following example illustrates this concept.<br />
<br />
Any NFS shares defined in {{ic|/etc/exports}} are relative to the NFS root. In this example, the NFS root will be {{ic|/srv/nfs}} and we are sharing {{ic|/mnt/music}}.<br />
<br />
# mkdir -p /srv/nfs/music /mnt/music<br />
<br />
Read/Write permissions must be set on the music directory so clients may write to it. <br />
<br />
Now mount the actual target share, {{ic|/mnt/music}} to the directory under the NFS root via the mount --bind command:<br />
<br />
# mount --bind /mnt/music /srv/nfs/music<br />
<br />
To make it stick across server reboots, add the bind mount to {{ic|fstab}}:<br />
<br />
{{hc|/etc/fstab|<br />
/mnt/music /srv/nfs/music none bind 0 0<br />
}}<br />
<br />
{{Note|[[ZFS]] filesystems require special handling of bindmounts, see [[ZFS#Bind mount]].}}<br />
<br />
Add directories to be shared and an ip address or hostname(s) of client machines that will be allowed to mount them in {{ic|exports}}:<br />
<br />
{{hc|/etc/exports|<nowiki><br />
/srv/nfs 192.168.1.0/24(rw,fsid=root,no_subtree_check)<br />
/srv/nfs/music 192.168.1.0/24(rw,no_subtree_check,nohide) # note the nohide option which is applied to mounted directories on the file system.<br />
</nowiki>}}<br />
<br />
{{Note|If the target export is a tmpfs filesystem, the {{ic|1=fsid=1}} option is required.}}<br />
<br />
Users need-not open the share to the entire subnet; one can specify a single IP address or hostname as well.<br />
<br />
For more information about all available options see {{man|5|exports}}.<br />
<br />
{{Note|Modifying {{ic|/etc/exports}} while the server is running will require a re-export for changes to take effect as noted by the upstream comments in {{ic|/etc/exports}}:<br />
<br />
# exportfs -rav<br />
<br />
}}<br />
<br />
==== Starting the server ====<br />
<br />
[[Start]] and [[enable]] {{ic|nfs-server.service}}.<br />
<br />
==== Miscellaneous ====<br />
<br />
===== Optional configuration =====<br />
<br />
Advanced configuration options can be set in {{ic|/etc/nfs.conf}}. Users setting up a simple configuration may not need to edit this file.<br />
<br />
===== Restricting NFS to interfaces/IPs =====<br />
<br />
By default, starting {{ic|nfs-server.service}} will listen for connections on all network interfaces, regardless of {{ic|/etc/exports}}. This can be changed by defining which IPs and/or hostnames to listen on.<br />
<br />
{{hc|/etc/nfs.conf|2=<br />
[nfsd]<br />
host=192.168.1.123<br />
# Alternatively, you can use your hostname.<br />
# host=myhostname<br />
}}<br />
<br />
Restarting the service will apply the changes immediately. <br />
<br />
# systemctl restart nfs-server.service<br />
<br />
===== Ensure NFSv4 idmapping is fully enabled =====<br />
<br />
Even though idmapd may be running, it may not be fully enabled. Verify by checking {{ic|cat /sys/module/nfsd/parameters/nfs4_disable_idmapping}} returns {{ic|N}}. If not:<br />
<br />
# echo "N" | sudo tee /sys/module/nfsd/parameters/nfs4_disable_idmapping<br />
<br />
Set this to survive reboots by adding an option to the nfs kernel module:<br />
<br />
# echo "options nfs nfs4_disable_idmapping=0" | sudo tee -a /etc/modprobe.d/nfs.conf<br />
<br />
(See [https://bbs.archlinux.org/viewtopic.php?pid=1530693#p1530693 this forum reply] for more information.)<br />
<br />
If journalctl reports lines like the following when starting nfs-server.service and nfs-idmapd.service, then this may be the solution.<br />
<br />
rpc.idmapd[25010]: nfsdcb: authbuf=192.168.0.0/16 authtype=user<br />
rpc.idmapd[25010]: nfsdcb: bad name in upcall<br />
<br />
===== Static ports for NFSv3 =====<br />
{{Out of date|Configuration should be done in /etc/nfs.conf since {{Pkg|nfs-utils}} 2.1.1.[https://sourceforge.net/projects/nfs/files/nfs-utils/2.1.1/]}}<br />
Users needing support for NFSv3 clients, may wish to consider using static ports. By default, for NFSv3 operation {{ic|rpc.statd}} and {{ic|lockd}} use random ephemeral ports; in order to allow NFSv3 operations through a firewall static ports need to be defined. Edit {{ic|/etc/sysconfig/nfs}} to set {{ic|STATDARGS}}:<br />
<br />
{{hc|/etc/sysconfig/nfs|2=<br />
STATDARGS="-p 32765 -o 32766 -T 32803"<br />
}}<br />
<br />
The {{ic|rpc.mountd}} should consult {{ic|/etc/services}} and bind to the same static port 20048 under normal operation; however, if it needs to be explicity defined edit {{ic|/etc/sysconfig/nfs}} to set {{ic|RPCMOUNTDARGS}}:<br />
<br />
{{hc|/etc/sysconfig/nfs|2=<br />
RPCMOUNTDARGS="-p 20048"<br />
}}<br />
<br />
After making these changes, several services need to be restarted; the first writes the configuration options out to {{ic|/run/sysconfig/nfs-utils}} (see {{ic|/usr/lib/systemd/scripts/nfs-utils_env.sh}}), the second restarts {{ic|rpc.statd}} with the new ports, the last reloads {{ic|lockd}} (kernel module) with the new ports. [[Restart]] these services now: {{ic|nfs-config}}, {{ic|rpcbind}}, {{ic|rpc-statd}}, and {{ic|nfs-server}}.<br />
<br />
After the restarts, use {{ic|rpcinfo -p}} on the server to examine the static ports are as expected. Using {{ic|rpcinfo -p <server IP>}} from the client should reveal the exact same static ports.<br />
<br />
===== NFSv2 compatibility =====<br />
{{Out of date|Configuration should be done in /etc/nfs.conf since {{Pkg|nfs-utils}} 2.1.1.[https://sourceforge.net/projects/nfs/files/nfs-utils/2.1.1/]}}<br />
Users needing to support clients using NFSv2 (for example U-Boot), should set {{ic|1=RPCNFSDARGS="-V 2"}} in {{ic|/etc/sysconfig/nfs}}.<br />
<br />
===== Firewall configuration =====<br />
<br />
To enable access through a firewall, tcp and udp ports 111, 2049, and 20048 need to be opened when using the default configuration; use {{ic|rpcinfo -p}} to examine the exact ports in use on the server. To configure this for [[iptables]], execute this commands:<br />
<br />
# iptables -A INPUT -p tcp -m tcp --dport 111 -j ACCEPT<br />
# iptables -A INPUT -p tcp -m tcp --dport 2049 -j ACCEPT<br />
# iptables -A INPUT -p tcp -m tcp --dport 20048 -j ACCEPT<br />
# iptables -A INPUT -p udp -m udp --dport 111 -j ACCEPT<br />
# iptables -A INPUT -p udp -m udp --dport 2049 -j ACCEPT<br />
# iptables -A INPUT -p udp -m udp --dport 20048 -j ACCEPT<br />
<br />
To have this configuration load on every system start, edit {{ic|/etc/iptables/iptables.rules}} to include the following lines:<br />
<br />
{{hc|/etc/iptables/iptables.rules|<nowiki><br />
-A INPUT -p tcp -m tcp --dport 111 -j ACCEPT<br />
-A INPUT -p tcp -m tcp --dport 2049 -j ACCEPT<br />
-A INPUT -p tcp -m tcp --dport 20048 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 111 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 2049 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 20048 -j ACCEPT<br />
</nowiki>}}<br />
<br />
The previous commands can be saved by executing:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
{{note|This command will '''override''' the current iptables start configuration with the current iptables configuration!}}<br />
<br />
If using NFSv3 and the above listed static ports for {{ic|rpc.statd}} and {{ic|lockd}} these also need to be added to the configuration:<br />
<br />
{{hc|/etc/iptables/iptables.rules|<nowiki><br />
-A INPUT -p tcp -m tcp --dport 32765 -j ACCEPT<br />
-A INPUT -p tcp -m tcp --dport 32803 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 32765 -j ACCEPT<br />
-A INPUT -p udp -m udp --dport 32803 -j ACCEPT<br />
</nowiki>}}<br />
<br />
If using V4-only setup, only tcp port 2049 need to be opened. Therefore only one line needed.<br />
<br />
{{hc|/etc/iptables/iptables.rules|<nowiki><br />
-A INPUT -p tcp -m tcp --dport 2049 -j ACCEPT<br />
</nowiki>}}<br />
<br />
To apply changes, [[Restart]] {{ic|iptables.service}}.<br />
<br />
=== Client ===<br />
Users intending to use NFS4 with [[Kerberos]], also need to [[start]] and [[enable]] {{ic|nfs-client.target}}, which starts {{ic|rpc-gssd.service}}. However, due to bug {{Bug|50663}} in glibc, {{ic|rpc-gssd.service}} currently fails to start. Adding the "-f" (foreground) flag in the service is a workaround:<br />
<br />
{{hc|# systemctl edit rpc-gssd.service|2=<br />
[Unit]<br />
Requires=network-online.target<br />
After=network-online.target<br />
<br />
[Service]<br />
Type=simple<br />
ExecStart=<br />
ExecStart=/usr/sbin/rpc.gssd -f<br />
}}<br />
<br />
==== Error from systemd ====<br />
<br />
Users experiencing the following may consider turning off the service using system's masking feature: "Dependency failed for pNFS block layout mapping daemon."<br />
<br />
Example:<br />
<br />
# systemctl mask nfs-blkmap.service<br />
<br />
==== Manual mounting ====<br />
<br />
For NFSv3 use this command to show the server's exported file systems:<br />
<br />
$ showmount -e servername<br />
<br />
For NFSv4 mount the root NFS directory and look around for available mounts:<br />
<br />
# mount server:/ /mountpoint/on/client<br />
<br />
Then mount omitting the server's NFS export root: <br />
<br />
# mount -t nfs -o vers=4 servername:/music /mountpoint/on/client<br />
<br />
If mount fails try including the server's export root (required for Debian/RHEL/SLES, some distributions need {{ic|-t nfs4}} instead of {{ic|-t nfs}}):<br />
<br />
# mount -t nfs -o vers=4 servername:/full/path/to/music /mountpoint/on/client<br />
<br />
{{Note|Server name needs to be a valid hostname (not just IP address). Otherwise mounting of remote share will hang.}}<br />
<br />
==== Mount using /etc/fstab ====<br />
<br />
Using [[fstab]] is useful for a server which is always on, and the NFS shares are available whenever the client boots up. Edit {{ic|/etc/fstab}} file, and add an appropriate line reflecting the setup. Again, the server's NFS export root is omitted.<br />
<br />
{{hc|/etc/fstab|<nowiki><br />
servername:/music /mountpoint/on/client nfs rsize=8192,wsize=8192,timeo=14,_netdev 0 0<br />
</nowiki>}}<br />
<br />
{{Note|Consult {{man|5|nfs}} and {{man|8|mount}} for more mount options.}}<br />
<br />
Some additional mount options to consider are include:<br />
<br />
; rsize and wsize: The {{ic|rsize}} value is the number of bytes used when reading from the server. The {{ic|wsize}} value is the number of bytes used when writing to the server. The default for both is 1024, but using higher values such as 8192 can improve throughput. This is not universal. It is recommended to test after making this change, see [[#Performance tuning]].<br />
<br />
; timeo: The {{ic|timeo}} value is the amount of time, in tenths of a second, to wait before resending a transmission after an RPC timeout. After the first timeout, the timeout value is doubled for each retry for a maximum of 60 seconds or until a major timeout occurs. If connecting to a slow server or over a busy network, better performance can be achieved by increasing this timeout value. <br />
<br />
; _netdev: The {{ic|_netdev}} option tells the system to wait until the network is up before trying to mount the share. systemd assumes this for NFS, but anyway it is good practice to use it for all types of networked file systems<br />
<br />
{{Note|Setting the sixth field ({{ic|fs_passno}}) to a nonzero value may lead to unexpected behaviour, e.g. hangs when the systemd automount waits for a check which will never happen.}}<br />
<br />
==== Mount using /etc/fstab with systemd ====<br />
<br />
Another method is using the systemd {{ic|automount}} service. This is a better option than {{ic|_netdev}}, because it remounts the network device quickly when the connection is broken and restored. As well, it solves the problem from autofs, see the example below:<br />
<br />
{{hc|1=/etc/fstab|2=<br />
servername:/home ''/mountpoint/on/client'' nfs noauto,x-systemd.automount,x-systemd.device-timeout=10,timeo=14,x-systemd.idle-timeout=1min 0 0 <br />
}}<br />
<br />
One might have to reboot the client to make systemd aware of the changes to fstab. Alternatively, try [[Systemd#Using_units|reloading]] systemd and restarting {{ic|''mountpoint-on-client''.automount}} to reload the {{ic|/etc/fstab}} configuration.<br />
<br />
{{Tip|<br />
* The {{ic|noauto}} mount option will not mount the NFS share until it is accessed: use {{ic|auto}} for it to be available immediately. <br> If experiencing any issues with the mount failing due to the network not being up/available, [[enable]] {{ic|NetworkManager-wait-online.service}}. It will ensure that {{ic|network.target}} has all the links available prior to being active.<br />
* The {{ic|users}} mount option would allow user mounts, but be aware it implies further options as {{ic|noexec}} for example.<br />
* The {{ic|<nowiki>x-systemd.idle-timeout=1min</nowiki>}} option will unmount the NFS share automatically after 1 minute of non-use. Good for laptops which might suddenly disconnect from the network.<br />
* If shutdown/reboot holds too long because of NFS, [[enable]] {{ic|NetworkManager-wait-online.service}} to ensure that NetworkManager is not exited before the NFS volumes are unmounted. You may also try to add the {{ic|<nowiki>x-systemd.requires=network.target</nowiki>}} mount option if shutdown takes too long. }}<br />
<br />
{{Note|Users trying to automount a NFS-share via systemd which is mounted the same way on the server may experience a freeze when handling larger amounts of data.}}<br />
<br />
==== Mount using autofs ====<br />
<br />
Using [[autofs]] is useful when multiple machines want to connect via NFS; they could both be clients as well as servers. The reason this method is preferable over the earlier one is that if the server is switched off, the client will not throw errors about being unable to find NFS shares. See [[autofs#NFS network mounts]] for details.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Performance tuning ===<br />
<br />
In order to get the most out of NFS, it is necessary to tune the {{ic|rsize}} and {{ic|wsize}} mount options to meet the requirements of the network configuration.<br />
<br />
=== Automounting shares with systemd-networkd ===<br />
<br />
Users making use of systemd-networkd might notice nfs mounts the fstab are not mounted when booting; errors like the following are common:<br />
<br />
mount[311]: mount.nfs4: Network is unreachable<br />
<br />
The solution is simple; force systemd to wait for the network to be completely configured by [[enabling]] {{ic|systemd-networkd-wait-online.service}}. In theory this slows down the boot-process because less services run in parallel.<br />
<br />
=== Automatic mount handling ===<br />
<br />
This trick is useful for laptops that require nfs shares from a local wireless network. If the nfs host becomes unreachable, the nfs share will be unmounted to hopefully prevent system hangs when using the hard mount option. See https://bbs.archlinux.org/viewtopic.php?pid=1260240#p1260240<br />
<br />
Make sure that the NFS mount points are correctly indicated in {{ic|/etc/fstab}}:<br />
<br />
{{hc|$ cat /etc/fstab|<nowiki><br />
lithium:/mnt/data /mnt/data nfs noauto,noatime,rsize=32768,wsize=32768 0 0<br />
lithium:/var/cache/pacman /var/cache/pacman nfs noauto,noatime,rsize=32768,wsize=32768 0 0</nowiki><br />
}}<br />
<br />
{{Note|You must use hostnames in {{ic|/etc/fstab}} for this to work, not IP addresses.}}<br />
<br />
The {{ic|noauto}} mount option tells systemd not to automatically mount the shares at boot. systemd would otherwise attempt to mount the nfs shares that may or may not exist on the network causing the boot process to appear to stall on a blank screen.<br />
<br />
In order to mount NFS shares with non-root users the {{ic|user}} option has to be added. <br />
<br />
Create the {{ic|auto_share}} script that will be used by ''cron'' or ''systemd/Timers'' to use ICMP ping to check if the NFS host is reachable:<br />
<br />
{{hc|/usr/local/bin/auto_share|<nowiki><br />
#!/bin/bash<br />
<br />
function net_umount {<br />
umount -l -f $1 &>/dev/null<br />
}<br />
<br />
function net_mount {<br />
mountpoint -q $1 || mount $1<br />
}<br />
<br />
NET_MOUNTS=$(sed -e '/^.*#/d' -e '/^.*:/!d' -e 's/\t/ /g' /etc/fstab | tr -s " ")$'\n'b<br />
<br />
printf %s "$NET_MOUNTS" | while IFS= read -r line<br />
do<br />
SERVER=$(echo $line | cut -f1 -d":")<br />
MOUNT_POINT=$(echo $line | cut -f2 -d" ")<br />
<br />
# Check if server already tested<br />
if [[ "${server_ok[@]}" =~ "${SERVER}" ]]; then<br />
# The server is up, make sure the share are mounted<br />
net_mount $MOUNT_POINT<br />
elif [[ "${server_notok[@]}" =~ "${SERVER}" ]]; then<br />
# The server could not be reached, unmount the share<br />
net_umount $MOUNT_POINT<br />
else<br />
# Check if the server is reachable<br />
ping -c 1 "${SERVER}" &>/dev/null<br />
<br />
if [ $? -ne 0 ]; then<br />
server_notok[${#Unix[@]}]=$SERVER<br />
# The server could not be reached, unmount the share<br />
net_umount $MOUNT_POINT<br />
else<br />
server_ok[${#Unix[@]}]=$SERVER<br />
# The server is up, make sure the share are mounted<br />
net_mount $MOUNT_POINT<br />
fi<br />
fi<br />
done<br />
</nowiki>}}<br />
<br />
{{Note|If you want to test using a TCP probe instead of ICMP ping (default is tcp port 2049 in NFS4) then replace the line:<br />
<br />
# Check if the server is reachable<br />
ping -c 1 "${SERVER}" &>/dev/null<br />
<br />
with:<br />
<br />
# Check if the server is reachable<br />
timeout 1 bash -c ": < /dev/tcp/${SERVER}/2049"<br />
<br />
in the {{ic|auto_share}} script above.}}<br />
<br />
# chmod +x /usr/local/bin/auto_share<br />
<br />
Create a cron entry or a systemd/Timers timer to check every minute if the server of the shares are reachable.<br />
<br />
==== Cron ====<br />
<br />
{{hc|# crontab -e|<nowiki><br />
* * * * * /usr/local/bin/auto_share<br />
</nowiki>}}<br />
<br />
==== systemd/Timers ====<br />
<br />
{{hc|# /etc/systemd/system/auto_share.timer|<nowiki><br />
[Unit]<br />
Description=Check the network mounts<br />
<br />
[Timer]<br />
OnCalendar=*-*-* *:*:00<br />
<br />
[Install]<br />
WantedBy=timer.target<br />
</nowiki>}}<br />
<br />
{{hc|# /etc/systemd/system/auto_share.service|<nowiki><br />
[Unit]<br />
Description=Check the network mounts<br />
<br />
[Service]<br />
Type=simple<br />
ExecStart=/usr/local/bin/auto_share<br />
</nowiki>}}<br />
<br />
# systemctl enable auto_share.timer<br />
<br />
==== Mount at startup via systemd ====<br />
<br />
A systemd unit file can also be used to mount the NFS shares at startup. The unit file is not necessary if NetworkManager is installed and configured on the client system. See [[#NetworkManager dispatcher]].<br />
<br />
{{hc|/etc/systemd/system/auto_share.service|<nowiki><br />
[Unit]<br />
Description=NFS automount<br />
After=syslog.target network.target<br />
<br />
[Service]<br />
Type=oneshot<br />
RemainAfterExit=yes<br />
ExecStart=/usr/local/bin/auto_share<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
</nowiki>}}<br />
<br />
Now [[enable]] the {{ic|auto_share.service}}.<br />
<br />
==== NetworkManager dispatcher ====<br />
<br />
In addition to the method described previously, [[NetworkManager#Network_services_with_NetworkManager_dispatcher|NetworkManager]] can also be configured to run a script on network status change: [[Enable]] and [[start]] the {{ic|NetworkManager-dispatcher.service}}.<br />
<br />
The easiest method for mount shares on network status change is to just symlink to the {{ic|auto_share}} script:<br />
<br />
# ln -s /usr/local/bin/auto_share /etc/NetworkManager/dispatcher.d/30-nfs.sh<br />
<br />
However, in that particular case unmounting will happen only after the network connection has already been disabled, which is unclean and may result in effects like freezing of KDE Plasma applets. <br />
<br />
The following script safely unmounts the NFS shares before the relevant network connection is disabled by listening for the {{ic|pre-down}} and {{ic|vpn-pre-down}} events:<br />
<br />
{{Note|This script ignores mounts with the noauto option.}}<br />
<br />
{{hc|/etc/NetworkManager/dispatcher.d/30-nfs.sh|<nowiki><br />
#!/bin/bash<br />
<br />
# Find the connection UUID with "nmcli con show" in terminal.<br />
# All NetworkManager connection types are supported: wireless, VPN, wired...<br />
WANTED_CON_UUID="CHANGE-ME-NOW-9c7eff15-010a-4b1c-a786-9b4efa218ba9"<br />
<br />
if [[ "$CONNECTION_UUID" == "$WANTED_CON_UUID" ]]; then<br />
<br />
# Script parameter $1: NetworkManager connection name, not used<br />
# Script parameter $2: dispatched event<br />
<br />
case "$2" in<br />
"up")<br />
mount -a -t nfs4,nfs <br />
;;<br />
"pre-down");&<br />
"vpn-pre-down")<br />
umount -l -a -t nfs4,nfs >/dev/null<br />
;;<br />
esac<br />
fi<br />
</nowiki>}}<br />
<br />
Make the script executable with [[chmod]] and create a symlink inside {{ic|/etc/NetworkManager/dispatcher.d/pre-down}} to catch the {{ic|pre-down}} events:<br />
<br />
# ln -s /etc/NetworkManager/dispatcher.d/30-nfs.sh /etc/NetworkManager/dispatcher.d/pre-down.d/30-nfs.sh<br />
<br />
The above script can be modified to mount different shares (even other than NFS) for different connections.<br />
<br />
See also: [[NetworkManager#Use dispatcher to handle mounting of CIFS shares]].<br />
<br />
== Troubleshooting ==<br />
<br />
There is a dedicated article [[NFS Troubleshooting]].<br />
<br />
== See also ==<br />
<br />
* See also [[Avahi]], a Zeroconf implementation which allows automatic discovery of NFS shares.<br />
* HOWTO: [[Diskless network boot NFS root]]<br />
* [http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.prftungd/doc/prftungd/nfs_perf.htm NFS Performance Management]<br />
* [http://blogs.msdn.com/sfu/archive/2008/04/14/all-well-almost-about-client-for-nfs-configuration-and-performance.aspx Microsoft Services for Unix NFS Client info]<br />
* [https://blogs.oracle.com/jag/entry/nfs_on_snow_leopard NFS on Snow Leopard]</div>Chehrihttps://wiki.archlinux.org/index.php?title=Grsecurity&diff=411126Grsecurity2015-12-06T22:17:51Z<p>Chehri: VirtualBox isn't compatible.</p>
<hr />
<div>[[Category:Kernel]]<br />
[[Category:Security]]<br />
[[ja:Grsecurity]]<br />
{{Related articles start}}<br />
{{Related|PaX}}<br />
{{Related|Security}}<br />
{{Related|sysctl}}<br />
{{Related articles end}}<br />
<br />
[https://grsecurity.net/ Grsecurity] is an extensive security enhancement to the Linux kernel that defends against a wide range of security threats. The [[PaX]] project is included, hardening both userspace applications and the kernel against memory corruption-based exploits. Grsecurity includes a powerful Mandatory Access Control system with an effortless automatic learning mode and a host of other miscellaneous hardening features.<br />
<br />
== Installation ==<br />
<br />
The {{pkg|linux-grsec}} package in the [[official repositories]] provides the grsecurity hardened kernel. In most cases, grsecurity is a drop-in replacement for the vanilla kernel and will not cause any issues. By default, many of the user-facing features are disabled, but there is significant hardening of the kernel itself against exploitation.<br />
<br />
{{Note|The {{pkg|linux-grsec-lts}}{{Broken package link|{{aur-mirror|linux-grsec-lts}}}} package used to provide the 3.14 stable branch but it is [https://grsecurity.net/announce.php no longer available].}}<br />
<br />
After installing the {{pkg|linux-grsec}} or {{pkg|linux-grsec-lts}}{{Broken package link|{{aur-mirror|linux-grsec-lts}}}} package, you need to edit your [[bootloader]] settings to load vmlinuz-linux-grsec and initramfs-linux-grsec.img.<br />
<br />
Installing the optional {{pkg|paxd}} package causes the PaX exploit mitigations to be enabled, protecting userspace processes. It automatically applies the necessary exceptions for packages in the repositories. See [[PaX#PaX exceptions]] for more details.<br />
<br />
Also included are {{pkg|checksec}}, {{pkg|pax-utils}} and {{pkg|paxtest}} packages providing useful tooling for working with PaX and verifying that the exploit mitigation techniques are active.<br />
<br />
The optional {{pkg|gradm}} package provides the userspace tooling for managing RBAC policies. RBAC is disabled by default, and the sample policy is not usable without significant configuration (likely via heavy use of the learning mode).<br />
<br />
=== Custom kernel ===<br />
<br />
Compiling a custom kernel based on the official package with [[ABS]] is worth considering. There are several important compromises to make between performance and security, so while the official configuration is solid it is not perfect for every use case. See [[PaX#Performance]] for coverage of the PaX options with a significant performance impact. The official package prioritizes security over performance.<br />
<br />
The /proc and /sys restrictions are unacceptable for a general purpose package due to breaking too much software, but can be worth enabling to plug potential information leaks.<br />
<br />
Some features like the RANDSTRUCT plugin and hiding symbol addresses are only truly useful with a custom kernel, since the pre-built kernel is available for analysis by any attacker. The {{pkg|linux-grsec}} package enables {{ic|CONFIG_RANDOMIZE_BASE}}, but a custom build can provide unique symbol offsets in addition to the randomized base, making {{ic|CONFIG_GRKERNSEC_HIDESYM}} valuable.<br />
<br />
{{AUR|linux-libre-grsec}} and {{AUR|linux-zen-grsec}} are also available.<br />
<br />
== Compatibility ==<br />
<br />
{{Note|An incompatibility between {{pkg|linux-grsec}} and another package should not be reported as a bug in that package. It should be filed against the {{pkg|linux-grsec}} package and will either be fixed or documented as a compatibility issue here.}}<br />
<br />
The following incompatibilities require building a custom kernel with fewer features enabled:<br />
<br />
* hibernation is not supported (conflicts with {{ic|CONFIG_GRKERNSEC_KMEM}}, {{ic|CONFIG_PAX_MEMORY_SANITIZE}} and {{ic|CONFIG_RANDOMIZE_BASE}})<br />
* Xen and {{pkg|virtualbox}} are not supported (conflicts with {{ic|CONFIG_PAX_KERNEXEC}} and {{ic|CONFIG_PAX_MEMORY_UDEREF}})<br />
<br />
Known incompatibilities with other packages:<br />
<br />
* {{pkg|pkgstats}} - tries to list the loaded modules as non-root and treats it as a fatal error when it fails<br />
* {{aur|broadcom-wl-dkms}} - fails to be compiled with {{pkg|linux-grsec-headers}} due to illegal memory access<br />
<br />
Out-of-tree modules may require patches for compatibility with kernel hardening features like {{ic|CONFIG_PAX_SIZE_OVERFLOW}}:<br />
<br />
* the {{aur|nvidia-grsec}} package in the [[AUR]] patches the proprietary [[NVIDIA]] driver for compatibility with the {{ic|CONFIG_PAX_USERCOPY}} and {{ic|CONFIG_PAX_CONSTIFY_PLUGIN}} features<br />
<br />
== PaX ==<br />
<br />
The [[Wikipedia:PaX|PaX]] project provides many of the exploit mitigations offered by grsecurity. See [[PaX|the documentation on PaX]] for more information.<br />
<br />
== Configuration ==<br />
<br />
The user-facing features are configurable at runtime via [[sysctl]] settings. Sane defaults are set in the {{ic|/etc/sysctl.d/05-grsecurity.conf}} configuration file and it can be modified as desired.<br />
<br />
== Trusted path execution ==<br />
<br />
Trusted path execution (TPE) is an opt-in feature restricting file execution. It can be enabled by setting the {{ic|kernel.grsecurity.tpe}} [[sysctl]] switch to {{ic|1}}. TPE prevents users from executing any file writeable by a non-root user. By tightening up the rules for executing files, some exploits (such as upload + CGI exploits on a web server) and persistent backdoors will be prevented.<br />
<br />
=== Using the {{ic|tpe}} group as a whitelist or blacklist ===<br />
<br />
By default, {{ic|kernel.grsecurity.tpe_invert}} is set to {{ic|1}}, causing TPE to operate with a whitelist-based model. It will be applied to every user that is not a member of the {{ic|tpe}} group. If {{ic|kernel.grsecurity.tpe_invert}} is set to {{ic|0}}, the {{ic|tpe}} group will instead function as a blacklist of users with the restriction, with users not in the group unaffected.<br />
<br />
The whitelist model is recommended, and adding non-system users to the whitelist is usually enough. It will slightly improve the isolation of services running as non-root while not getting in anyone's way.<br />
<br />
=== Compatibility ===<br />
<br />
[[Linux Containers|Containers]] or plain [[chroot]]s can throw a wrench into the ease of using TPE, as each one has a local {{ic|/etc/group}}. A group with the same id in the container will still work as a whitelist, but this will be broken if the container makes use of user namespaces (not yet supported by Arch kernels).<br />
<br />
=== Partially restrict all non-root users ===<br />
<br />
Setting the {{ic|kernel.grsecurity.tpe_restrict_all}} [[sysctl]] switch to {{ic|1}} will prevent non-root users from executing files writeable by a user other than themselves or root. This feature is enabled by the default {{ic|/etc/sysctl.d/05-grsecurity.conf}}.<br />
<br />
== chroot hardening ==<br />
<br />
A [[chroot]] is a common isolation mechanism for services. Grsecurity includes features for eliminating many common escape routes from chroots and can lock them down to the point where the confinement is equivalent to a container. These features can all be toggled on and off via sysctl switches. For a detailed explanantion of these features, see the [https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Chroot_jail_restrictions configuration documentation].<br />
<br />
The following features are enabled in {{ic|/etc/sysctl.d/05-grsecurity.conf}} by default and are unlikely to cause any compatibility issues:<br />
<br />
kernel.grsecurity.chroot_deny_fchdir = 1<br />
kernel.grsecurity.chroot_deny_shmat = 1<br />
kernel.grsecurity.chroot_deny_sysctl = 1<br />
kernel.grsecurity.chroot_deny_unix = 1<br />
kernel.grsecurity.chroot_enforce_chdir = 1<br />
kernel.grsecurity.chroot_findtask = 1<br />
<br />
The remaining features are left off by default, to remain compatible with containers:<br />
<br />
#kernel.grsecurity.chroot_caps = 1<br />
#kernel.grsecurity.chroot_deny_chmod = 1<br />
#kernel.grsecurity.chroot_deny_chroot = 1<br />
#kernel.grsecurity.chroot_deny_mknod = 1<br />
#kernel.grsecurity.chroot_deny_mount = 1<br />
#kernel.grsecurity.chroot_deny_pivot = 1<br />
#kernel.grsecurity.chroot_restrict_nice = 1<br />
<br />
== Socket restrictions ==<br />
<br />
There are 3 groups for restricting access to sockets. Users in the {{ic|socket-deny-client}} group are forbidden from connecting to other hosts. Users in the {{ic|socket-deny-server}} group are unable to listen on a port. The {{ic|socket-deny-all}} group includes both of the restrictions.<br />
<br />
== Auditing ==<br />
<br />
There are a few security-related logging features added to the kernel.<br />
<br />
By default, only {{ic|kernel.grsecurity.rwxmap_logging}} is enabled. It logs an error whenever an application has an {{ic|mprotect}} or {{ic|mmap}} system call rejected due to the PaX MPROTECT feature along with some other edge cases. In most cases, the application is intentionally doing dynamic machine code generation and just needs an exception. However, it may indicate a compiler / linker bug or a bug in application / library code and the errors will also be logged when an exploit attempt is prevented by the MPROTECT feature. See [[PaX]] for more information about exceptions.<br />
<br />
The remaining audit features are currently disabled by default due to the high number of false positives, but can be enabled via [[sysctl]]. The {{ic|kernel.grsecurity.audit_group}} switch can be set to {{ic|1}} to limit {{ic|kernel.grsecurity.audit_chdir}} and {{ic|kernel.grsecurity.exec_logging}} to users in the {{ic|audit}} group as they will generate a LOT of log messages.<br />
<br />
== Hide information from /proc ==<br />
<br />
The {{pkg|linux-grsec}} package does not enable the strict {{ic|/proc}} restrictions ({{ic|CONFIG_GRKERNSEC_PROC}}). Instead, the {{ic|1=hidepid=2}} mount option can be set on {{ic|/proc}} to hide processes of other users and the {{ic|gid}} option can be used to make a group with an exception from the restrictions. The {{ic|hidepid}} mount option is less invasive because it's local to each process namespace so it can be set per [[systemd-nspawn|container]]. However, it's missing the additional miscellaneous information hiding so compiling a custom kernel may be desired.<br />
<br />
The {{pkg|hidepid}} package can be installed to set up the necessary {{ic|systemd-logind}} exception and enable {{ic|1=hidepid=2}}. It will also work with {{ic|CONFIG_GRKERNSEC_PROC}} in a custom kernel configured to use the correct proc group gid.<br />
<br />
== RBAC ==<br />
<br />
{{poor writing|reason=This section needs an overhaul, including fixing some inaccuracies.}}<br />
<br />
Role Based Access Control<br />
<br />
There are two basic types of access control mechanisms used to prevent unauthorized access to files (or information in general): DAC (Discretionary Access Control) and MAC (Mandatory Access Control). By default, Linux uses a DAC mechanism: the creator of the file can define who has access to the file. A MAC system however forces everyone to follow rules set by the administrator.<br />
<br />
The MAC implementation grsecurity supports is called Role Based Access Control. RBAC associates roles with each user. Each role defines what operations can be performed on certain objects. Given a well-written collection of roles and operations your users will be restricted to perform only those tasks that you tell them they can do. The default "deny-all" ensures you that a user cannot perform an action you have not thought of.<br />
<br />
=== Working with gradm ===<br />
<br />
{{pkg|gradm}} is a tool which allows you to administer and maintain a policy for your system. With it, you can enable or disable the RBAC system, reload the RBAC roles, change your role, set a password for admin mode, etc.<br />
<br />
When you install gradm a default policy will be installed in /etc/grsec/policy.<br />
<br />
By default, the RBAC policies are not activated. It is the sysadmin's job to determine when the system should have an RBAC policy enforced. Before activating the RBAC system you should set an admin password.<br />
<br />
# gradm -P admin<br />
Setting up grsecurity RBAC password<br />
Password: (Enter a well-chosen password)<br />
Re-enter Password: (Enter the same password for confirmation)<br />
Password written in /etc/grsec/pw<br />
# gradm -E<br />
<br />
To disable the RBAC system, run gradm -D. If you are not allowed to, you first need to switch to the admin role:<br />
<br />
# gradm -a admin<br />
Password: (Enter your admin role password)<br />
# gradm -D<br />
<br />
If you want to leave the admin role, run gradm -u admin:<br />
<br />
# gradm -u admin<br />
<br />
=== Generating a policy ===<br />
<br />
The RBAC system comes with a great feature called "learning mode". The learning mode can generate an anticipatory least privilege policy for your system. This allows for time and money savings by being able to rapidly deploy multiple secure servers.<br />
<br />
To use the learning mode, activate it using gradm:<br />
<br />
# gradm -F -L /etc/grsec/learning.log<br />
<br />
Now use your system, do the things you would normally do. Try to avoid rsyncing, running locate or any other heavy file i/o operation as this can really slow down the processing time.<br />
<br />
When you believe you have used your system sufficiently to obtain a good policy, let gradm process them and propose roles under {{ic|/etc/grsec/learning.roles}}:<br />
<br />
# gradm -D<br />
# gradm -F -L /etc/grsec/learning.log -O /etc/grsec/learning.roles<br />
<br />
Audit the {{ic|/etc/grsec/learning.roles}} and save it as {{ic|/etc/grsec/policy}} (mode {{ic|0600}}) when you are finished.<br />
<br />
# mv /etc/grsec/learning.roles /etc/grsec/policy<br />
# chmod 0600 /etc/grsec/policy<br />
<br />
You will now be able to enable the RBAC system with your new learned policy.<br />
<br />
# gradm -E<br />
<br />
{{Tip|If you receive the error '''Viewing access is allowed by role <insert user> to /etc/grsec, the directory which stores RBAC policies and RBAC password information.''', add the following to your '''subject /''' under '''# Role: <insert user>''':<br />
<br />
/etc/grsec h<br />
<br />
Example:<br />
<br />
# Role: root<br />
subject / {<br />
/ h<br />
/etc rx<br />
/etc/grsec h<br />
}}<br />
The reasoning for this can be found [https://forums.grsecurity.net/viewtopic.php?f=5&t=1607 here]<br />
<br />
=== Tweaking your policy ===<br />
<br />
An interesting feature of grsecurity 2.x is Set Operation Support for the configuration file. Currently it supports unions, intersections and differences of sets (of objects in this case).<br />
<br />
define objset1 {<br />
/root/blah rw<br />
/root/blah2 r<br />
/root/blah3 x<br />
}<br />
<br />
define somename2 {<br />
/root/test1 rw<br />
/root/blah2 rw<br />
/root/test3 h<br />
}<br />
<br />
Here is an example of its use, and the resulting objects that will be added to your subject:<br />
<br />
subject /somebinary o<br />
$objset1 & $somename2<br />
<br />
The above would expand to:<br />
<br />
subject /somebinary o<br />
/root/blah2 r<br />
<br />
This is the result of the & operator which takes both sets and returns the files that exist in both sets and the permission for those files that exist in both sets.<br />
<br />
subject /somebinary o<br />
$objset1 | $somename2<br />
<br />
This example would expand to:<br />
<br />
subject /somebinary o<br />
/root/blah rw<br />
/root/blah2 rw<br />
/root/blah3 x<br />
/root/test1 rw<br />
/root/test3 h<br />
<br />
This is the result of the | operator which takes both sets and returns the files that exist in either set. If a file exists in both sets, it is returned as well and the mode contains the flags that exist in either set.<br />
<br />
subject /somebinary o<br />
$objset1 - $somename2<br />
<br />
This example would expand to:<br />
<br />
subject /somebinary o<br />
/root/blah rw<br />
/root/blah2 h<br />
/root/blah3 x<br />
<br />
This is the result of the - operator which takes both sets and returns the files that exist in the set on the left but not in the match of the file in set on the right. If a file exists on the left and a match is found on the right (either the filenames are the same, or a parent directory exists in the right set), the file is returned and the mode of the second set is removed from the first set, and that file is returned.<br />
<br />
In some obscure pseudo-language you could see this as:<br />
<br />
if ( ($objset1 contained /tmp/blah rw) and<br />
($objset2 contained /tmp/blah r) )<br />
then<br />
$objset1 - $objset2 would contain /tmp/blah w<br />
<br />
if ( ($objset1 contained /tmp/blah rw) and<br />
($objset2 contained / rwx) )<br />
then <br />
$objset1 - $objset2 would contain /tmp/blah h<br />
<br />
As for order of precedence (from highest to lowest): "-, & |".<br />
<br />
If you do not want to bother remembering precedence, parenthesis support is also included, so you can do things like:<br />
<br />
(($set1 - $set2) | $set3) & $set4<br />
<br />
=== Tweaking /etc/grsec/policy directly ===<br />
<br />
Sometimes, full learning mode doesnt work for a particular program and direct revisions to the policy file will need to be made. One might simply want to tweak the policy file to add or remove access to directories without requiring one to reinitiate learning mode or recreating a policy file. The file itself is composed of Roles and Subjects. A Role determines what user the ruleset applies to, while the Subject could be seen as what process/program the ruleset applies to. <br />
<br />
Consider a situation where the role is "username", while the subject is /usr/lib/firefox/firefox. Within the curly braces of this role/subject rule, directories will be listed, along with flags that dictate what capacities (read, write, execute, etc) you wish to give that subject (firefox for example) under that role (username, when firefox is ran under the user "username" for example). Here is a list of flags and what they do:<br />
<br />
a This object can be opened for appending.<br />
c Allow creation of the file/directory.<br />
d Allow deletion of the file/directory.<br />
f Needed to mark the pipe used for communication with init to transfer the privilege of the persistent role; only valid within a persistent role. Transfer only occurs when the file is opened for writing.<br />
h This object is hidden.<br />
i This mode only applies to binaries. When the object is executed, it inherits the ACL of the subject in which it was contained.<br />
l Lowercase L. Allow a hardlink at this path. Hardlinking requires a minimum of c and l modes, and the target link cannot have any greater permission than the source file.<br />
m Allow creation of setuid/setgid files/directories and modification of files/directories to be setuid/setgid.<br />
p Reject all ptraces to this object.<br />
r This object can be opened for reading.<br />
t This object can be ptraced, but cannot modify the running task. This is referred to as a 'read-only ptrace'.<br />
w This object can be opened for writing or appending.<br />
x This object can be executed (or mmap'd with PROT_EXEC into a task).<br />
<br />
So for example, if you want firefox to have read access to the home folder of the user username, be able to do everything (read, write, create and destroy files, execute) in /home/username/Downloads, but not be able to see /home/username/secretstuff or anything in /, your ruleset might look like this:<br />
# Role: username<br />
subject /usr/lib/firefox/firefox o {<br />
/ h<br />
/home/username r<br />
/home/username/Downloads rwxcd<br />
/home/username/secretstuff h<br />
}<br />
Of course, a Firefox ruleset will need more than just the above (like access to directories it needs to run in /usr for example); compare the above with what is generated by full-learning-mode and you quickly see the pattern. The idea is that you want to limit each process as much as possible to limit the changes it can make to the filesystem in the event it is compromised. Much more info is available on the [http://en.wikibooks.org/wiki/Grsecurity/The_RBAC_System GRsecurity RBAC wiki page.]<br />
<br />
=== Using Wine; Changes needed to /etc/grsec/policy ===<br />
<br />
In the event you use wine, your executables for wine apps are on an NTFS partition, and you want it to work while RBAC is enabled, you will need to append "O" to the Subject mode of /usr/bin/wine-preloader for the Role (user) using this subject. I am unsure if this applies to executables in .wine as I do not have the free space to test it. I put my system into full-learning mode and ran wine, and after generating a /etc/grsec/policy from this session RBAC still prevented my wine program from running with:<br />
grsec: (username:U:/usr/bin/wine-preloader) denied load of writable library /mnt/winblows/Program Files (x86)/Diablo II/Game.exe by /usr/bin/wine-preloader[Game.exe:7518] uid...<br />
<br />
Appending "O" to the end of the Subject mode will fix this problem. An example of a working ruleset (notice the capital O after subject /usr/bin/wine-preloader):<br />
# Role: username<br />
subject /usr/bin/wine-preloader O {<br />
/ r<br />
<other listed files generated by full-learning mode> rwcdx<br />
}<br />
<br />
"O" is one of a number of flags you might append to the Subject mode. Others include:<br />
A Protect the shared memory of this subject. No other processes but processes contained within this subject may access the shared memory of this subject.<br />
C Auto-kill all processes belonging to the attacker's IP address upon violation of security policy.<br />
K When processes belonging to this subject generate an alert, kill the process.<br />
O Allow loading of writable libraries.<br />
T Deny execution of binaries or scripts that are writable by any other subject in the policy. This flag is evaluated at policy enable time. All binaries with execute permission that are writable by another subject (ignoring special roles) will be reported and the RBAC system will not allow itself to be enabled until the changes are made.<br />
<br />
See [http://en.wikibooks.org/wiki/Grsecurity/Appendix/Subject_Modes this link.]<br />
<br />
== Troubleshooting ==<br />
=== Out-of-tree kernel module compilation failure ===<br />
<br />
PaX and grsecurity implement some hardening features via GCC plugins. The compiler configuration / version used to build the plugins provided in the package needs to be the same when building a kernel module. For example, the compiler provided in the {{pkg|gcc-multilib}} package will not work - one should use the same compiler toolchain that was used to build the kernel. This also means {{pkg|linux-grsec}} needs to be rebuilt after even minor GCC upgrades before modules built with the new compiler can work with it. Rebuilding a kernel can be accomplished with the [[Kernels/Arch_Build_System|Arch Build System]]. See bug {{bug|43057}}.</div>Chehrihttps://wiki.archlinux.org/index.php?title=Dm-crypt/Device_encryption&diff=409964Dm-crypt/Device encryption2015-11-23T17:47:34Z<p>Chehri: Give hint about encrypting /boot.</p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:Encryption]]<br />
[[Category:File systems]]<br />
[[ja:Dm-crypt/デバイスの暗号化]]<br />
Back to [[Dm-crypt]].<br />
<br />
This section covers how to manually utilize ''dm-crypt'' from the command line to encrypt a system. <br />
<br />
== Preparation ==<br />
Before using {{pkg|cryptsetup}}, always make sure the {{ic|dm-crypt}} [[kernel module]] is loaded.<br />
<br />
== Cryptsetup usage ==<br />
''Cryptsetup'' is the command line tool to interface with ''dm-crypt'' for creating, accessing and managing encrypted devices. The tool was later expanded to support different encryption types that rely on the Linux kernel '''d'''evice-'''m'''apper and the '''crypt'''ographic modules. The most notable expansion was for the Linux Unified Key Setup (LUKS) extension, which stores all of the needed setup information for dm-crypt on the disk itself and abstracts partition and key management in an attempt to improve ease of use. Devices accessed via the device-mapper are called blockdevices. For further information see [[Disk encryption#Block device encryption]]. <br />
<br />
The tool is used as follows: <br />
<br />
# cryptsetup <OPTIONS> <action> <action-specific-options> <device> <dmname><br />
<br />
It has compiled-in defaults for the options and the encryption mode, which will be used if no others are specified on the command line. Have a look at <br />
<br />
$ cryptsetup --help <br />
<br />
which lists options, actions and the default parameters for the encryption modes in that order. A full list of options can be found on the man page.<br />
Since different parameters are required or optional, depending on encryption mode and action, the following sections point out differences further. Blockdevice encryption is fast, but speed matters a lot too. Since changing an encryption cipher of a blockdevice after setup is difficult, it is important to check ''dm-crypt'' performance for the individual parameters in advance: <br />
<br />
$ cryptsetup benchmark <br />
<br />
can give guidance on deciding for an algorithm and key-size prior to installation. If certain AES ciphers excel with a considerable higher throughput, these are probably the ones with hardware support in the CPU.<br />
<br />
{{Tip|You may want to practise encrypting a virtual hard drive in a [[:Category:Virtualization|virtual machine]] when learning.}}<br />
<br />
=== Cryptsetup passphrases and keys ===<br />
An encrypted blockdevice is protected by a key. A key is either: <br />
<br />
* a passphrase: see [[Disk encryption#Choosing a strong passphrase]].<br />
* a keyfile, see [[#Keyfiles]].<br />
<br />
Both key types have default maximum sizes: passphrases can be up to 512 characters and keyfiles up to 8192kB. <br />
<br />
An important distinction of ''LUKS'' to note at this point is that the key is used to unlock the master-key of a LUKS-encrypted device and can be changed with root access. Other encryption modes do not support changing the key after setup, because they do not employ a master-key for the encryption. See [[Disk encryption#Block device encryption]] for details.<br />
<br />
== Encryption options with dm-crypt ==<br />
''Cryptsetup'' supports different encryption operating modes to use with ''dm-crypt''. The most common (and default) is <br />
*{{ic|--type LUKS}} <br />
The other ones are <br />
*{{ic|--type plain}} for using dm-crypt plain mode, <br />
*{{ic|--type loopaes}} for a loopaes legacy mode, and <br />
*{{ic|--type tcrypt}} for a [[Truecrypt]] compatibility mode. <br />
<br />
The basic cryptographic options for encryption cipher and hashes available can be used for all modes and rely on the kernel cryptographic backend features. All that are loaded at runtime can be viewed with <br />
$ less /proc/crypto <br />
and are available to use as options. If the list is short, execute {{ic|cryptsetup benchmark}} which will trigger loading available modules. <br />
<br />
The following introduces encryption options for the first two modes. Note that the tables list options used in the respective examples in this article and not all available ones. <br />
<br />
=== Encryption options for LUKS mode ===<br />
<br />
The ''cryptsetup'' action to set up a new dm-crypt device in LUKS encryption mode is ''luksFormat''. Unlike the name implies, it does not format the device, but sets up the LUKS device header and encrypts the master-key with the desired cryptographic options. <br />
<br />
As LUKS is the default encryption mode,<br />
<br />
# cryptsetup -v luksFormat <device><br />
<br />
is all that is needed to create a new LUKS device with default parameters ({{ic|-v}} is optional). For comparison, we can specify the default options manually too: <br />
<br />
# cryptsetup -v --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time 2000 --use-urandom --verify-passphrase luksFormat <device> <br />
<br />
Defaults are compared with a somewhat ''extreme'' example with accompanying comments in the table below: <br />
<br />
{| class="wikitable"<br />
! scope="col" style="text-align:left" | Options<br />
! scope="col" style="text-align:left" | Cryptsetup 1.7.0 defaults <br />
! scope="col" style="text-align:left" | Example<br />
! scope="col" style="text-align:left" | Comment<br />
|-<br />
! scope="row" style="text-align:right" | --cipher, -c<br />
| {{ic|aes-xts-plain64}}<br />
| {{ic|aes-xts-plain64}}<br />
| [https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/v1.6.0-ReleaseNotes Release 1.6.0] changed the defaults to an AES [[Disk encryption#Ciphers_and_modes_of_operation|cipher]] in [[wikipedia:Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29|XTS]] mode (see item 5.16 [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#5-security-aspects of the FAQ]). It is advised against using the previous default {{ic|--cipher aes-cbc-essiv}} because of its known [https://en.wikipedia.org/wiki/Disk_encryption_theory#Cipher-block_chaining_.28CBC.29 issues] and practical [http://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/ attacks] against them.<br />
|-<br />
! scope="row" style="text-align:right" | --key-size, -s<br />
| {{ic|256}}<br />
| {{ic|512}}<br />
| By default a 256 bit key-size is used. Note however that [[wikipedia:Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29|XTS splits the supplied key in half]], so to use AES-256 instead of AES-128 you have to set the XTS key-size to {{ic|512}}.<br />
|-<br />
! scope="row" style="text-align:right" | --hash, -h<br />
| {{ic|sha256}}<br />
| {{ic|sha512}}<br />
| Hash algorithm used for [[Disk_encryption#Cryptographic_metadata|key derivation]]. Release 1.7.0 changed defaults from {{ic|sha1}} to {{ic|sha256}} "''not for security reasons [but] mainly to prevent compatibility problems on hardened systems where SHA1 is already [being] phased out''"[https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.0-ReleaseNotes]. The former default of {{ic|sha1}} can still be used for compatibility with older versions of ''cryptsetup'' since it is [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#5-security-aspects considered secure] (see item 5.20). <br />
|-<br />
! scope="row" style="text-align:right" | --iter-time, -i<br />
| {{ic|2000}}<br />
| {{ic|5000}}<br />
| Number of milliseconds to spend with PBKDF2 passphrase processing. Release 1.7.0 changed defaults from {{ic|1000}} to {{ic|2000}} to "''try to keep PBKDF2 iteration count still high enough and also still acceptable for users.''"[https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.0-ReleaseNotes]. This option is only relevant for LUKS operations that set or change passphrases, such as ''luksFormat'' or ''luksAddKey''. Specifying 0 as parameter selects the compiled-in default..<br />
|-<br />
! scope="row" style="text-align:right" | --use-{u,}random<br />
| {{ic|--use-urandom}}<br />
| {{ic|--use-random}}<br />
| [[Random number generation|/dev/urandom]] is used by default as randomness source for the (long-term) volume master key, which is [http://www.2uo.de/myths-about-urandom/ practically] [http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ always] [https://www.mail-archive.com/cryptography@randombit.net/msg04748.html better]. However {{ic|/dev/random}} can be used for key generation in an entropy-starved situation (e.g. automatic installation on an embedded device without network and other entropy sources).<br />
|-<br />
! scope="row" style="text-align:right" | --verify-passphrase, -y<br />
| Yes<br />
| -<br />
| Default only for luksFormat and luksAddKey. No need to type for Arch Linux with LUKS mode at the moment. <br />
|}<br />
<br />
=== Encryption options for plain mode ===<br />
In dm-crypt ''plain'' mode, there is no master-key on the device, hence, there is no need to set it up. Instead the encryption options to be employed are used directly to create the mapping between an encrypted disk and a named device. The mapping can be created against a partition or a full device. In the latter case not even a partition table is needed. <br />
<br />
To create a ''plain'' mode mapping with cryptsetup's default parameters: <br />
# cryptsetup <options> open --type plain <device> <dmname><br />
Executing it will prompt for a password, which should have very high entropy. <br />
Below a comparison of default parameters with the example in [[Dm-crypt/Encrypting an entire system#Plain dm-crypt]]<br />
<br />
{| class="wikitable"<br />
! Option !! Cryptsetup 1.7.0 defaults !! Example !! Comment<br />
|-<br />
| '''--hash''' || {{ic|ripemd160}} || - || The hash is used to create the key from the passphrase; it is not used on a keyfile. <br />
|-<br />
| '''--cipher'''|| {{ic|aes-cbc-essiv:sha256}}|| {{ic|twofish-xts-plain64}} || The cipher consists of three parts: cipher-chainmode-IV generator. Please see [[Disk encryption#Ciphers and modes of operation]] for an explanation of these settings, and the [https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt DMCrypt documentation] for some of the options available. <br />
|-<br />
| '''--key-size'''||{{ic|256}}||{{ic|512}}||The key size (in bits). The size will depend on the cipher being used and also the chainmode in use. Xts mode requires twice the key size of cbc. <br />
|-<br />
| '''--offset'''||{{ic|0}}||{{ic|0}}||The offset from the beginning of the target disk from which to start the mapping<br />
|-<br />
| '''--key-file'''||default uses a passphrase||{{ic|/dev/sd''Z''}} (or e.g. /boot/keyfile.enc)||The device or file to be used as a key. See [[#Keyfiles]] for further details.<br />
|-<br />
| '''--keyfile-offset'''||{{ic|0}}||{{ic|0}}||Offset from the beginning of the file where the key starts (in bytes). This option is supported from ''cryptsetup'' 1.6.7 onwards. <br />
|-<br />
| '''--keyfile-size'''||{{ic|8192kB}}||- (default applies)||Limits the bytes read from the key file. This option is supported from ''cryptsetup'' 1.6.7 onwards. <br />
|}<br />
<br />
Using the device {{ic|/dev/sd''X''}}, the above right column example results in:<br />
{{bc|<nowiki># cryptsetup --cipher=twofish-xts-plain64 --offset=0 --key-file=</nowiki>/dev/sd''Z'' <nowiki>--key-size=512 open --type=plain /dev/sdX enc</nowiki>}}<br />
Unlike encrypting with LUKS, the above command must be executed ''in full'' whenever the mapping needs to be re-established, so it is important to remember the cipher, hash and key file details.<br />
We can now check that the mapping has been made:<br />
# fdisk -l<br />
An entry should now exist for {{ic|/dev/mapper/enc}}.<br />
<br />
== Encrypting devices with cryptsetup ==<br />
This section shows how to employ the options for creating new encrypted blockdevices and accessing them manually. <br />
<br />
=== Encrypting devices with LUKS mode ===<br />
==== Formatting LUKS partitions ====<br />
<br />
In order to setup a partition as an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup -c <cipher> -y -s <key size> luksFormat /dev/<partition name>|<br />
Enter passphrase: <password><br />
Verify passphrase: <password>}}<br />
first to setup the encrypted master-key. Checking results can be done with:<br />
# cryptsetup luksDump /dev/<drive><br />
<br />
This should be repeated for all partitions to be encrypted (except for {{ic|/boot}}). You will note that the dump not only shows the cipher header information, but also the key-slots in use for the LUKS partition. <br />
<br />
The following example will create an encrypted root partition using the default AES cipher in XTS mode with an effective 256-bit encryption <br />
{{bc|# cryptsetup -s 512 luksFormat /dev/sdaX}}<br />
<br />
=====Using LUKS to Format Partitions with a Keyfile=====<br />
<br />
When creating a new LUKS encrypted partition, a keyfile may be associated with the partition on its creation using:<br />
<br />
# cryptsetup -c <desired cipher> -s <key size> luksFormat /dev/<volume to encrypt> '''/path/to/mykeyfile'''<br />
<br />
This is accomplished by appending the bold area to the standard cryptsetup command which defines where the keyfile is located.<br />
<br />
See [[#Keyfiles]] for instructions on how to generate and manage keyfiles.<br />
<br />
====Unlocking/Mapping LUKS partitions with the device mapper ====<br />
<br />
Once the LUKS partitions have been created it is time to unlock them.<br />
<br />
The unlocking process will map the partitions to a new device name using the device mapper. This alerts the kernel that {{ic|/dev/<partition name>}} is actually an encrypted device and should be addressed through LUKS using the {{ic|/dev/mapper/<name>}} so as not to overwrite the encrypted data. To guard against accidental overwriting, read about the possibilities to [[Dm-crypt/Device encryption#Backup_and_restore|backup the cryptheader]] after finishing setup.<br />
<br />
In order to open an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup open --type luks /dev/<partition name> <device-mapper name>|<br />
Enter any LUKS passphrase: <password><br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
Usually the device mapped name is descriptive of the function of the partition that is mapped, example:<br />
<br />
# cryptsetup open --type luks /dev/sdaX root <br />
Once opened, the root partition device address would be {{ic|/dev/mapper/root}} instead of the partition (e.g. {{ic|/dev/sdaX}}). <br />
<br />
# cryptsetup open --type luks /dev/sda3 lvmpool <br />
For setting up LVM ontop the encryption layer the device file for the decrypted volume group would be anything like {{ic|/dev/mapper/lvmpool}} instead of {{ic|/dev/sdaX}}. LVM will then give additional names to all logical volumes created, e.g. {{ic|/dev/mapper/lvmpool-root}} and {{ic|/dev/mapper/lvmpool-swap}}.<br />
<br />
In order to write encrypted data into the partition it must be accessed through the device mapped name. The first step of access will typically be to create a filesystem <br />
# mkfs -t ext4 /dev/mapper/root<br />
and mount it <br />
# mount -t ext4 /dev/mapper/root /mnt<br />
The mounted blockdevice can then be used like any other partition. Once done, closing the device locks it again <br />
# umount /mnt<br />
# cryptsetup close root<br />
<br />
=== Encrypting devices with plain mode ===<br />
<br />
The creation and subsequent access of a ''dm-crypt'' plain mode encryption both require not more than using the ''cryptsetup'' {{ic|open}} action with correct [[Dm-crypt/Device encryption#Encryption_options_for_plain_mode|parameters]]. The following shows that with two examples of non-root devices, but adds a quirk by stacking both (i.e. the second is created inside the first). Obviously, stacking the encryption doubles overhead. The usecase here is simply to illustrate another example of the cipher option usage. <br />
<br />
A first mapper is created with ''cryptsetup's'' plain-mode defaults, as described in the table's left column above <br />
# cryptsetup --type plain -v open /dev/sdaX plain1 <br />
Enter passphrase: <br />
Command successful.<br />
# <br />
Now we add the second blockdevice inside it, using different encryption parameters and with an (optional) offset, create a filesystem and mount it <br />
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/mapper/plain1 plain2<br />
Enter passphrase: <br />
# lsblk -p <br />
NAME <br />
/dev/sda <br />
├─/dev/sdaX <br />
│ └─/dev/mapper/plain1 <br />
│ └─/dev/mapper/plain2 <br />
...<br />
# mkfs -t ext2 /dev/mapper/plain2<br />
# mount -t ext2 /dev/mapper/plain2 /mnt<br />
# echo "This is stacked. one passphrase per foot to shoot." > /mnt/stacked.txt<br />
We close the stack to check access works<br />
# cryptsetup close plain2<br />
# cryptsetup close plain1<br />
First, let's try to open the filesystem directly: <br />
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/sdaX plain2<br />
# mount -t ext2 /dev/mapper/plain2 /mnt<br />
mount: wrong fs type, bad option, bad superblock on /dev/mapper/plain2,<br />
missing codepage or helper program, or other error<br />
Why that did not work? Because the "plain2" starting block (10) is still encrypted with the cipher from "plain1". It can only be accessed via the stacked mapper. The error is arbitrary though, trying a wrong passphrase or wrong options will yield the same. For ''dm-crypt'' plain mode, the {{ic|open}} action will not error out itself. <br />
<br />
Trying again in correct order: <br />
# cryptsetup close plain2 # dysfunctional mapper from previous try<br />
# cryptsetup --type plain open /dev/sdaX plain1<br />
Enter passphrase: <br />
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/mapper/plain1 plain2 <br />
Enter passphrase: <br />
# mount /dev/mapper/plain2 /mnt && cat /mnt/stacked.txt<br />
This is stacked. one passphrase per foot to shoot.<br />
# exit<br />
''dm-crypt'' will handle stacked encryption with some mixed modes too. For example LUKS mode could be stacked on the "plain1" mapper. Its header would then be encrypted inside "plain1" when that is closed.<br />
<br />
Available for plain mode only is the option {{ic|--shared}}. With it a single device can be segmented into different non-overlapping mappers. We do that in the next example, using a ''loopaes'' compatible cipher mode for "plain2" this time: <br />
# cryptsetup --type plain --offset 0 --size 1000 open /dev/sdaX plain1 <br />
Enter passphrase: <br />
# cryptsetup --type plain --offset 1000 --size 1000 --shared --cipher=aes-cbc-lmk --hash=sha256 open /dev/sdaX plain2<br />
Enter passphrase: <br />
# lsblk -p<br />
NAME <br />
dev/sdaX <br />
├─/dev/sdaX <br />
│ ├─/dev/mapper/plain1 <br />
│ └─/dev/mapper/plain2 <br />
...<br />
As the devicetree shows both reside on the same level, i.e. are not stacked and "plain2" can be opened individually.<br />
<br />
== Cryptsetup actions specific for LUKS ==<br />
=== Key management ===<br />
It is possible to define up to 8 different keys per LUKS partition. This enables the user to create access keys for save backup storage: In a so-called key escrow, one key is used for daily usage, another kept in escrow to gain access to the partition in case the daily passphrase is forgotten or a keyfile is lost/damaged. Also a different key-slot could be used to grant access to a partition to a user by issuing a second key and later revoking it again. <br />
<br />
Once an encrypted partition has been created, the initial keyslot 0 is created (if no other was specified manually). Additional keyslots are numbered from 1 to 7. Which keyslots are used can be seen by issuing <br />
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki>grep BLED|<br />
Key Slot 0: ENABLED<br />
Key Slot 1: ENABLED<br />
Key Slot 2: ENABLED<br />
Key Slot 3: DISABLED<br />
Key Slot 4: DISABLED<br />
Key Slot 5: DISABLED<br />
Key Slot 6: DISABLED<br />
Key Slot 7: DISABLED}}<br />
<br />
Where <device> is the volume containing the LUKS header. This and all the following commands in this section work on header backup files as well. <br />
<br />
==== Adding LUKS keys ====<br />
<br />
Adding new keyslots is accomplished using cryptsetup with the {{ic|luksAddKey}} action. For safety it will always, i.e. also for already unlocked devices, ask for a valid existing key ("any passphrase") before a new one may be entered:<br />
<br />
# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) <br />
Enter any passphrase:<br />
Enter new passphrase for key slot:<br />
Verify passphrase: <br />
<br />
If {{ic|/path/to/<additionalkeyfile>}} is given, cryptsetup will add a new keyslot for <additionalkeyfile>. Otherwise a new passphrase will be prompted for twice. For using an existing ''keyfile'' to authorize the action, the {{ic|--key-file}} or {{ic|-d}} option followed by the "old" <keyfile> will try to unlock all available keyfile keyslots:<br />
<br />
# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) -d /path/to/<keyfile><br />
<br />
If it is intended to use multiple keys and change or revoke them, the {{ic|--key-slot}} or {{ic|-S}} option may be used to specify the slot: <br />
# cryptsetup luksAddKey /dev/<device> -S 6 <br />
Enter any passphrase: <br />
Enter new passphrase for key slot: <br />
Verify passphrase:<br />
# cryptsetup luksDump /dev/sda8 |grep 'Slot 6'<br />
Key Slot 6: ENABLED<br />
<br />
To show an associated action in this example, we decide to change the key right away: <br />
# cryptsetup luksChangeKey /dev/<device> -S 6 <br />
Enter LUKS passphrase to be changed: <br />
Enter new LUKS passphrase: <br />
<br />
before continuing to remove it.<br />
<br />
==== Removing LUKS keys ====<br />
<br />
There are three different actions to remove keys from the header: <br />
*{{ic|luksRemoveKey}} is used to remove a key by specifying its passphrase/key-file. <br />
*{{ic|luksKillSlot}} may be used to remove a key from a specific key slot (using another key). Obviously, this is extremely useful if you have forgotten a passphrase, lost a key-file, or have no access to it. <br />
*{{ic|luksErase}} is used to quickly remove '''all''' active keys. <br />
{{warning|<br />
*All above actions can be used to irrevocably delete the last active key for an encrypted device! <br />
*The {{ic|luksErase}} command was added in version 1.6.4 to quickly nuke access to the device. This action '''will not''' prompt for a valid passphrase! It will not [[Dm-crypt/Drive_preparation#Wipe_LUKS_header|wipe the LUKS header]], but all keyslots at once and you will, therefore, not be able to regain access unless you have a valid backup of the LUKS header.}} <br />
<br />
For above warning it is good to know the key we want to '''keep''' is valid. An easy check is to unlock the device with the {{ic|-v}} option, which will specify which slot it occupies: <br />
{{bc|# cryptsetup -v open /dev/<device> testcrypt<br />
Enter passphrase for /dev/<device>: <br />
Key slot 1 unlocked.<br />
Command successful.}}<br />
<br />
Now we can remove the key added in the previous subsection using its passphrase: <br />
# cryptsetup luksRemoveKey /dev/<device><br />
Enter LUKS passphrase to be deleted: <br />
If we had used the same passphrase for two keyslots, the first slot would be wiped now. Only executing it again would remove the second one. <br />
<br />
Alternatively, we can specify the key slot: <br />
# cryptsetup luksKillSlot /dev/<device> 6<br />
Enter any remaining LUKS passphrase:<br />
<br />
Note that in both cases, no confirmation was required.<br />
# cryptsetup luksDump /dev/sda8 |grep 'Slot 6'<br />
Key Slot 6: DISABLED<br />
To re-iterate the warning above: If the same passphrase had been used for key slots 1 and 6, both would be gone now.<br />
<br />
=== Backup and restore ===<br />
If the header of a LUKS encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much as a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. A damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table.<br />
<br />
Therefore, having a backup of the header and storing it on another disk might be a good idea.<br />
<br />
'''Attention:''' Many people recommend NOT backing up the cryptheader, but even so it's a single point of failure!<br />
In short, the problem is that LUKS is not aware of the duplicated cryptheader, which contains the master key used to encrypt all files on the partition. Of course this master key is encrypted with your passphrases or keyfiles.<br />
But if one of those gets compromised and you want to revoke it you have to do this on all copies of the cryptheader!<br />
I.e. if someone obtains a copy of the cryptheader and one of your keys he can decrypt the master key and access all your data.<br />
Of course the same is true for all backups you create of partitions. So you decide if you are one of those paranoids brave enough to go without a backup for the sake of security or not. See also the [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#6-backup-and-data-recovery LUKS FAQ] for further details on this.<br />
<br />
==== Backup using cryptsetup ====<br />
Cryptsetup's {{ic|luksHeaderBackup}} action stores a binary backup of the LUKS header and keyslot area:<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /mnt/<backup>/<file>.img<br />
where <device> is the partition containing the LUKS volume.<br />
<br />
{{Tip|You can also back up the plaintext header into ramfs and encrypt it in example with gpg before writing to persistent backup storage by executing the following commands.}}<br />
{{bc|# mkdir /root/<tmp>/<br />
# mount ramfs /root/<tmp>/ -t ramfs<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /root/<tmp>/<file>.img<br />
# gpg2 --recipient <User ID> --encrypt /root/<tmp>/<file>.img <br />
# cp /root/<tmp>/<file>.img.gpg /mnt/<backup>/<br />
# umount /root/<tmp>}}<br />
{{Warning|Tmpfs can swap to harddisk if low on memory so it is not recommended here.}}<br />
<br />
==== Restore using cryptsetup ====<br />
<br />
{{Warning|Restoring the wrong header or restoring to an unencrypted partition will cause data loss! The action can not perform a check whether the header is actually the ''correct'' one for that particular device.}} <br />
<br />
In order to evade restoring a wrong header, you can ensure it does work by using it as a remote {{ic|--header}} first: <br />
<br />
# cryptsetup -v --header /mnt/<backup>/<file>.img open /dev/<device> test <br />
Key slot 0 unlocked.<br />
Command successful.<br />
# mount /dev/mapper/test /mnt/test && ls /mnt/test <br />
# umount /mnt/test <br />
# cryptsetup close test <br />
<br />
Now that the check succeeded, the restore may be performed: <br />
# cryptsetup luksHeaderRestore /dev/<device> --header-backup-file ./mnt/<backup>/<file>.img<br />
<br />
Now that all the keyslot areas are overwritten; only active keyslots from the backup file are available after issuing the command.<br />
<br />
==== Manual backup and restore ====<br />
The header always resides at the beginning of the device and a backup can be performed without access to ''cryptsetup'' as well. First you have to find out the payload offset of the crypted partition:<br />
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki> grep "Payload offset"|<br />
Payload offset: 4040}}<br />
Second check the sector size of the drive<br />
{{hc|# fdisk -l /dev/<device> <nowiki>|</nowiki>grep "Sector size"|Sector size (logical/physical): 512 bytes / 512 bytes}}<br />
<br />
Now that you know the values, you can backup the header with a simple dd command:<br />
# dd if=/dev/<device> of=/path/to/<file>.img bs=512 count=4040<br />
and store it safely.<br />
<br />
A restore can then be performed using the same values as when backing up:<br />
# dd if=./<file>.img of=/dev/<device> bs=512 count=4040<br />
<br />
=== Re-encrypting devices ===<br />
<br />
{{Expansion|Introduce ''cryptsetup-reencrypt''.|Talk:Dm-crypt/Specialties#Recommend TRIM on non-FDE SSDs.3F}}<br />
<br />
The {{Pkg|cryptsetup}} package features the ''cryptsetup-reencrypt'' tool. It can be used to convert an existing unencrypted filesystem to a LUKS encrypted one (option {{ic|--new}}) and permanently remove LUKS encryption ({{ic|--decrypt}}) from a device. As its name suggests it can also be used to re-encrypt an existing LUKS encrypted device. For re-encryption it is possible to change the [[#Encryption options for LUKS mode]]. ''cryptsetup-reencrypt'' actions can be performed to unmounted devices only. See {{ic|man cryptsetup-reencrypt}} for more information. <br />
<br />
One application of re-encryption may be to secure the data again after a passphrase or [[#Keyfiles|keyfile]] has been compromised ''and'' one cannot be certain that no copy of the LUKS header has been obtained. For example, if only a passphrase has been shoulder-surfed but no physical/logical access to the device happened, it would be enough to change the respective passphrase/key only ([[#Key management]]). <br />
<br />
{{Warning|The tool has been available and improved since 2012, but it is still marked '''experimental'''. Always make sure a '''reliable backup''' is available before using it!}}<br />
<br />
The following shows an example to encrypt an unencrypted filesystem partition and a re-encryption of an existing LUKS device. <br />
<br />
==== Encrypt an unencrypted filesystem ====<br />
<br />
A LUKS encryption header is always stored at the beginning of the device. Since an existing filesystem will usually be allocated all partition sectors, the first step is to shrink it to make space for the LUKS header. <br />
<br />
The [[#Encryption_options_for_LUKS_mode|default]] LUKS header encryption cipher requires {{ic|4096}} 512-byte sectors. We already checked space and keep it simple by shrinking the existing {{ic|ext4}} filesystem on {{ic|/dev/sdaX}} to its current possible minimum: <br />
<br />
{{bc|# umount /mnt<br />
# e2fsck -f /dev/sdaX <br />
e2fsck 1.43-WIP (18-May-2015)<br />
Pass 1: Checking inodes, blocks, and sizes<br />
...<br />
/dev/sda6: 12/166320 files (0.0% non-contiguous), 28783/665062 blocks<br />
# resize2fs -M /dev/sdaX<br />
resize2fs 1.43-WIP (18-May-2015)<br />
Resizing the filesystem on /dev/sdaX to 26347 (4k) blocks.<br />
The filesystem on /dev/sdaX is now 26347 (4k) blocks long.}}<br />
<br />
Now we encrypt it, using the default cipher we do not have to specify it explicitly. Note there is no option (yet) to double-check the passphrase before encryption starts, be careful not to mistype: <br />
<br />
{{hc|# cryptsetup-reencrypt /dev/sdaX --new --reduce-device-size 4096S|<br />
WARNING: this is experimental code, it can completely break your data.<br />
Enter new passphrase: <br />
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed 37,6 MiB/s}}<br />
<br />
After it finished, the encryption was performed to the full partition, i.e. not only the space the filesystem was shrunk to ({{ic|sdaX}} has {{ic|2.6GiB}} and the CPU used in the example has no hardware AES instructions). As a final step we extend the filesystem of the now encrypted device again to occupy available space: <br />
<br />
{{bc|# cryptsetup open /dev/sdaX recrypt <br />
Enter passphrase for /dev/sdaX: <br />
...<br />
# resize2fs /dev/mapper/recrypt <br />
resize2fs 1.43-WIP (18-May-2015)<br />
Resizing the filesystem on /dev/mapper/recrypt to 664807 (4k) blocks.<br />
The filesystem on /dev/mapper/recrypt is now 664807 (4k) blocks long.<br />
# mount /dev/mapper/recrypt /mnt}}<br />
<br />
and are done.<br />
<br />
==== Re-encrypting an existing LUKS partition ====<br />
<br />
In this example an existing LUKS device is re-encrypted. <br />
<br />
{{Warning|Double-check you specify encryption options for ''cryptsetup-reencrypt'' correctly and ''never'' re-encrypt without a '''reliable backup'''! As of September 2015 the tool '''does''' accept invalid options and damage the LUKS header, if not used correctly!}}<br />
<br />
In order to re-encrypt a device with its existing encryption options, they do not need to be specified. A simple: <br />
<br />
{{hc|# cryptsetup-reencrypt /dev/sdaX| <br />
WARNING: this is experimental code, it can completely break your data.<br />
Enter passphrase for key slot 0: <br />
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed 36,5 MiB/s}}<br />
<br />
performs it. <br />
<br />
A possible usecase is to re-encrypt LUKS devices which have non-current encryption options. Apart from above warning on specifying options correctly, the ability to change the LUKS header may also be limited by its size. For example, if the device was initially encrypted using a CBC mode cipher and 128 bit key-size, the LUKS header will be half the size of above mentioned {{ic|4096}} sectors: <br />
{{hc|# cryptsetup luksDump /dev/sdaX <nowiki>|</nowiki>grep -e "mode" -e "Payload" -e "MK bits"|<br />
Cipher mode: cbc-essiv:sha256<br />
Payload offset: '''2048'''<br />
MK bits: 128}}<br />
While it is possible to upgrade the encryption of such a device, it is currently only feasible in two steps. First, re-encrypting with the same encryption options, but using the {{ic|--reduce-device-size}} option to make further space for the larger LUKS header. Second, re-encypt the whole device again with the desired cipher. For this reason and the fact that a backup should be created in any case, creating a new, fresh encrypted device to restore into is always the faster option.<br />
<br />
== Keyfiles ==<br />
<br />
{{Note|This section describes using a plaintext keyfile. If you want to encrypt your keyfile giving you two factor authentication see [[Dm-crypt/Specialties#Using_GPG_or_OpenSSL_Encrypted_Keyfiles|Using GPG or OpenSSL Encrypted Keyfiles]] for details, but please still read this section.}}<br />
<br />
'''What is a keyfile?'''<br />
<br />
A keyfile is a file whose data is used as the passphrase to unlock an encrypted volume.<br />
That means if such a file is lost or changed, decrypting the volume may no longer be possible.<br />
<br />
{{Tip|Define a passphrase in addition to the keyfile for backup access to encrypted volumes in the event the defined keyfile is lost or changed.}}<br />
<br />
'''Why use a keyfile?'''<br />
<br />
There are many kinds of keyfiles. Each type of keyfile used has benefits and disadvantages summarized below:<br />
<br />
=== Types of keyfiles ===<br />
==== passphrase ====<br />
<br />
This is a keyfile containing a simple passphrase. The benefit of this type of keyfile is that if the file is lost the data it contained is known and hopefully easily remembered by the owner of the encrypted volume. However the disadvantage is that this does not add any security over entering a passphrase during the initial system start.<br />
<br />
Example: 1234<br />
<br />
==== randomtext ====<br />
<br />
This is a keyfile containing a block of random characters. The benefit of this type of keyfile is that it is much more resistant to dictionary attacks than a simple passphrase. An additional strength of keyfiles can be utilized in this situation which is the length of data used. Since this is not a string meant to be memorized by a person for entry, it is trivial to create files containing thousands of random characters as the key. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase.<br />
<br />
Example: fjqweifj830149-57 819y4my1-38t1934yt8-91m 34co3;t8y;9p3y-<br />
<br />
==== binary ====<br />
<br />
This is a binary file that has been defined as a keyfile. When identifying files as candidates for a keyfile, it is recommended to choose files that are relatively static such as photos, music, video clips. The benefit of these files is that they serve a dual function which can make them harder to identify as keyfiles. Instead of having a text file with a large amount of random text, the keyfile would look like a regular image file or music clip to the casual observer. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase. Additionally, there is a theoretical loss of randomness when compared to a randomly generated text file. This is due to the fact that images, videos and music have some intrinsic relationship between neighboring bits of data that does not exist for a text file. However this is controversial and has never been exploited publicly.<br />
<br />
Example: images, text, video, ...<br />
<br />
=== Creating a keyfile with random characters ===<br />
<br />
==== Storing the keyfile on a filesystem ====<br />
<br />
A keyfile can be of arbitrary content and size. <br />
<br />
Here {{ic|dd}} is used to generate a keyfile of 2048 random bytes, storing it in the file {{ic|/etc/mykeyfile}}:<br />
<br />
# dd bs=512 count=4 if=/dev/urandom of=/etc/mykeyfile iflag=fullblock<br />
<br />
If you are planning to store the keyfile on an external device, you can also simply change the outputfile to the corresponding directory:<br />
<br />
# dd bs=512 count=4 if=/dev/urandom of=/media/usbstick/mykeyfile iflag=fullblock<br />
<br />
===== Securely overwriting stored keyfiles =====<br />
<br />
If you stored your temporary keyfile on a physical storage device, and want to delete it, remember to not just remove the keyfile later on, but use something like<br />
<br />
# shred --remove --zero mykeyfile<br />
<br />
to securely overwrite it. For overaged filesystems like FAT or ext2 this will suffice while in the case of journaling filesystems, flash memory hardware and other cases it is highly recommended to [[Securely wipe disk|wipe the entire device]] or at least the keyfiles partition.<br />
<br />
==== Storing the keyfile in tmpfs ====<br />
<br />
Alternatively, you can mount a tmpfs for storing the keyfile temporarily:<br />
<br />
# mkdir mytmpfs<br />
# mount tmpfs mytmpfs -t tmpfs -o size=32m<br />
# cd mytmpfs<br />
<br />
The advantage is that it resides in RAM and not on a physical disk, therefore it can not be recovered after unmounting the tmpfs. On the other hand this requires you to copy the keyfile to another filesystem you consider secure before unmounting.<br />
<br />
=== Configuring LUKS to make use of the keyfile ===<br />
<br />
Add a keyslot for the keyfile to the LUKS header:<br />
<br />
{{hc|# cryptsetup luksAddKey /dev/sda2 mykeyfile|<br />
Enter any LUKS passphrase:<br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
=== Unlocking a secondary partition at boot ===<br />
<br />
If the keyfile for a secondary file system is itself stored inside an encrypted root, it is safe while the system is powered off but can be sourced to automatically unlock the mount during with boot via [[Dm-crypt/System configuration#crypttab|crypttab]]. Following above first example <br />
{{hc|/etc/crypttab|home /dev/sda2 /etc/mykeyfile}}<br />
is all needed for unlocking, and <br />
{{hc|/etc/fstab|/dev/mapper/home /home ext4 defaults 0 2}} for mounting the LUKS blockdevice with the generated keyfile.<br />
{{Tip|If you prefer to use a {{ic|--plain}} mode blockdevice, the encryption options necessary to unlock it are specified in {{ic|/etc/crypttab}}. Take care to apply the systemd workaround mentioned in [[Dm-crypt/System configuration#crypttab|crypttab]] in this case.}}<br />
<br />
=== Unlocking the root partition at boot ===<br />
<br />
This is simply a matter of configuring [[mkinitcpio]] to include the necessary modules or files and configuring the [[Dm-crypt/System_configuration#cryptkey|cryptkey]] [[Kernel_parameters|kernel parameter]] to know where to find the keyfile.<br />
<br />
Two cases will be covered:<br />
<br />
# Using a keyfile stored on an external media (here a USB stick)<br />
# Using a keyfile embedded in the initramfs <br />
<br />
==== With a keyfile stored on an external media ====<br />
<br />
===== Configuring mkinitcpio =====<br />
<br />
You have to add two extra modules in your {{ic|/etc/mkinitcpio.conf}}, one for the drive's file system ({{ic|vfat}} module in the example below) and one for the codepage ({{ic|nls_cp437}} module) :<br />
MODULES="nls_cp437 vfat"<br />
<br />
In this example it is assumed that you use a FAT formatted USB drive ({{ic|vfat}} module). Replace those module names if you use another file system on your USB stick (e.g. {{ic|ext2}}) or another codepage. Users running the stock Arch kernel should stick to the codepage mentioned here. If it complains of bad superblock and bad codepage at boot, then you need an extra codepage module to be loaded. For instance, you may need {{ic|nls_iso8859-1}} module for {{ic|iso8859-1}} codepage.<br />
<br />
If you have a non-US keyboard, it might prove useful to load your keyboard layout before you are prompted to enter the password to unlock the root partition at boot. For this, you will need the {{ic|keymap}} hook before {{ic|encrypt}}.<br />
<br />
Generate a new initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
===== Configuring the kernel parameters =====<br />
<br />
Add the following options to the [[kernel parameters]]:<br />
<br />
cryptdevice=/dev/''<partition1>'':root cryptkey=/dev/''<partition2>'':<fstype>:<path><br />
<br />
For example:<br />
<br />
cryptdevice=/dev/sda3:root cryptkey=/dev/sdb1:vfat:/keys/secretkey<br />
<br />
Choosing a plain filename for your key provides a bit of 'security through obscurity'. The keyfile can not be a hidden file, that means the filename must not start with a dot, or the {{ic|encrypt}} hook will fail to find the keyfile during the boot process.<br />
<br />
The naming of device nodes like {{ic|/dev/sdb1}} is not guaranteed to stay the same across reboots. It is more reliable to access the device with udev's [[persistent block device naming]] instead. To assure that the {{ic|encrypt}} hook finds your keyfile when reading it from an external storage device, persistent block device names must be used. See the article [[persistent block device naming]].<br />
<br />
==== With a keyfile embedded in the initramfs ====<br />
<br />
{{Warning|Use an embedded keyfile '''only''' if you have some form of authentication mechanism beforehand that protects the keyfile sufficiently. Otherwise auto-decryption will occur, defeating completely the purpose of block device encryption. Encrypting /boot is supported with GRUB 1.98 and beyond.}}<br />
<br />
This method allows to use a specially named keyfile that will be embedded in the [[initramfs]] and picked up by the {{ic|encrypt}} [[Mkinitcpio#HOOKS|hook]] to unlock the root filesystem automatically. It may be useful to apply when using the [[GRUB#Boot partition|GRUB early cryptodisk]] feature, in order to avoid entering two passphrases during boot.<br />
<br />
By default the {{ic|encrypt}} hook takes the file specified in the {{ic|cryptkey}} kernel parameter and use it to unlock {{ic|cryptdevice}}. However, the code defaults to use {{ic|/crypto_keyfile.bin}} if it exists.[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/encrypt_hook?h=packages/cryptsetup#n8] If the initramfs contains a valid key with this name, decryption will occur automatically without the need to configure the {{ic|cryptkey}} parameter.<br />
<br />
[[#Creating_a_keyfile_with_random_characters|Generate the keyfile]], give it suitable permissions and [[#Adding_LUKS_keys|add it as a LUKS key]]:<br />
<br />
# dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin<br />
# chmod 000 /crypto_keyfile.bin<br />
# chmod 600 /boot/initramfs-linux*<br />
# cryptsetup luksAddKey /dev/sdX# /crypto_keyfile.bin<br />
<br />
{{Warning|When initramfs' permissions are set to 644 (by default), then all users will be able to dump the keyfile. Make sure the permissions are still 600 if you install a new kernel.}}<br />
<br />
Include the key in [[Mkinitcpio#BINARIES_and_FILES|mkinitcpio FILES array]]:<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=FILES="/crypto_keyfile.bin"}}<br />
<br />
Finally [[Mkinitcpio#Image_creation_and_activation|Regenerate your initramfs]].<br />
<br />
On the next reboot you should only have to enter your container decryption passphrase once.<br />
<br />
([http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/#bonus-login-once source])</div>Chehrihttps://wiki.archlinux.org/index.php?title=Dm-crypt/Device_encryption&diff=409963Dm-crypt/Device encryption2015-11-23T17:31:05Z<p>Chehri: Typo correction. (600, not 400.)</p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:Encryption]]<br />
[[Category:File systems]]<br />
[[ja:Dm-crypt/デバイスの暗号化]]<br />
Back to [[Dm-crypt]].<br />
<br />
This section covers how to manually utilize ''dm-crypt'' from the command line to encrypt a system. <br />
<br />
== Preparation ==<br />
Before using {{pkg|cryptsetup}}, always make sure the {{ic|dm-crypt}} [[kernel module]] is loaded.<br />
<br />
== Cryptsetup usage ==<br />
''Cryptsetup'' is the command line tool to interface with ''dm-crypt'' for creating, accessing and managing encrypted devices. The tool was later expanded to support different encryption types that rely on the Linux kernel '''d'''evice-'''m'''apper and the '''crypt'''ographic modules. The most notable expansion was for the Linux Unified Key Setup (LUKS) extension, which stores all of the needed setup information for dm-crypt on the disk itself and abstracts partition and key management in an attempt to improve ease of use. Devices accessed via the device-mapper are called blockdevices. For further information see [[Disk encryption#Block device encryption]]. <br />
<br />
The tool is used as follows: <br />
<br />
# cryptsetup <OPTIONS> <action> <action-specific-options> <device> <dmname><br />
<br />
It has compiled-in defaults for the options and the encryption mode, which will be used if no others are specified on the command line. Have a look at <br />
<br />
$ cryptsetup --help <br />
<br />
which lists options, actions and the default parameters for the encryption modes in that order. A full list of options can be found on the man page.<br />
Since different parameters are required or optional, depending on encryption mode and action, the following sections point out differences further. Blockdevice encryption is fast, but speed matters a lot too. Since changing an encryption cipher of a blockdevice after setup is difficult, it is important to check ''dm-crypt'' performance for the individual parameters in advance: <br />
<br />
$ cryptsetup benchmark <br />
<br />
can give guidance on deciding for an algorithm and key-size prior to installation. If certain AES ciphers excel with a considerable higher throughput, these are probably the ones with hardware support in the CPU.<br />
<br />
{{Tip|You may want to practise encrypting a virtual hard drive in a [[:Category:Virtualization|virtual machine]] when learning.}}<br />
<br />
=== Cryptsetup passphrases and keys ===<br />
An encrypted blockdevice is protected by a key. A key is either: <br />
<br />
* a passphrase: see [[Disk encryption#Choosing a strong passphrase]].<br />
* a keyfile, see [[#Keyfiles]].<br />
<br />
Both key types have default maximum sizes: passphrases can be up to 512 characters and keyfiles up to 8192kB. <br />
<br />
An important distinction of ''LUKS'' to note at this point is that the key is used to unlock the master-key of a LUKS-encrypted device and can be changed with root access. Other encryption modes do not support changing the key after setup, because they do not employ a master-key for the encryption. See [[Disk encryption#Block device encryption]] for details.<br />
<br />
== Encryption options with dm-crypt ==<br />
''Cryptsetup'' supports different encryption operating modes to use with ''dm-crypt''. The most common (and default) is <br />
*{{ic|--type LUKS}} <br />
The other ones are <br />
*{{ic|--type plain}} for using dm-crypt plain mode, <br />
*{{ic|--type loopaes}} for a loopaes legacy mode, and <br />
*{{ic|--type tcrypt}} for a [[Truecrypt]] compatibility mode. <br />
<br />
The basic cryptographic options for encryption cipher and hashes available can be used for all modes and rely on the kernel cryptographic backend features. All that are loaded at runtime can be viewed with <br />
$ less /proc/crypto <br />
and are available to use as options. If the list is short, execute {{ic|cryptsetup benchmark}} which will trigger loading available modules. <br />
<br />
The following introduces encryption options for the first two modes. Note that the tables list options used in the respective examples in this article and not all available ones. <br />
<br />
=== Encryption options for LUKS mode ===<br />
<br />
The ''cryptsetup'' action to set up a new dm-crypt device in LUKS encryption mode is ''luksFormat''. Unlike the name implies, it does not format the device, but sets up the LUKS device header and encrypts the master-key with the desired cryptographic options. <br />
<br />
As LUKS is the default encryption mode,<br />
<br />
# cryptsetup -v luksFormat <device><br />
<br />
is all that is needed to create a new LUKS device with default parameters ({{ic|-v}} is optional). For comparison, we can specify the default options manually too: <br />
<br />
# cryptsetup -v --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time 2000 --use-urandom --verify-passphrase luksFormat <device> <br />
<br />
Defaults are compared with a somewhat ''extreme'' example with accompanying comments in the table below: <br />
<br />
{| class="wikitable"<br />
! scope="col" style="text-align:left" | Options<br />
! scope="col" style="text-align:left" | Cryptsetup 1.7.0 defaults <br />
! scope="col" style="text-align:left" | Example<br />
! scope="col" style="text-align:left" | Comment<br />
|-<br />
! scope="row" style="text-align:right" | --cipher, -c<br />
| {{ic|aes-xts-plain64}}<br />
| {{ic|aes-xts-plain64}}<br />
| [https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/v1.6.0-ReleaseNotes Release 1.6.0] changed the defaults to an AES [[Disk encryption#Ciphers_and_modes_of_operation|cipher]] in [[wikipedia:Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29|XTS]] mode (see item 5.16 [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#5-security-aspects of the FAQ]). It is advised against using the previous default {{ic|--cipher aes-cbc-essiv}} because of its known [https://en.wikipedia.org/wiki/Disk_encryption_theory#Cipher-block_chaining_.28CBC.29 issues] and practical [http://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/ attacks] against them.<br />
|-<br />
! scope="row" style="text-align:right" | --key-size, -s<br />
| {{ic|256}}<br />
| {{ic|512}}<br />
| By default a 256 bit key-size is used. Note however that [[wikipedia:Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29|XTS splits the supplied key in half]], so to use AES-256 instead of AES-128 you have to set the XTS key-size to {{ic|512}}.<br />
|-<br />
! scope="row" style="text-align:right" | --hash, -h<br />
| {{ic|sha256}}<br />
| {{ic|sha512}}<br />
| Hash algorithm used for [[Disk_encryption#Cryptographic_metadata|key derivation]]. Release 1.7.0 changed defaults from {{ic|sha1}} to {{ic|sha256}} "''not for security reasons [but] mainly to prevent compatibility problems on hardened systems where SHA1 is already [being] phased out''"[https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.0-ReleaseNotes]. The former default of {{ic|sha1}} can still be used for compatibility with older versions of ''cryptsetup'' since it is [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#5-security-aspects considered secure] (see item 5.20). <br />
|-<br />
! scope="row" style="text-align:right" | --iter-time, -i<br />
| {{ic|2000}}<br />
| {{ic|5000}}<br />
| Number of milliseconds to spend with PBKDF2 passphrase processing. Release 1.7.0 changed defaults from {{ic|1000}} to {{ic|2000}} to "''try to keep PBKDF2 iteration count still high enough and also still acceptable for users.''"[https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.0-ReleaseNotes]. This option is only relevant for LUKS operations that set or change passphrases, such as ''luksFormat'' or ''luksAddKey''. Specifying 0 as parameter selects the compiled-in default..<br />
|-<br />
! scope="row" style="text-align:right" | --use-{u,}random<br />
| {{ic|--use-urandom}}<br />
| {{ic|--use-random}}<br />
| [[Random number generation|/dev/urandom]] is used by default as randomness source for the (long-term) volume master key, which is [http://www.2uo.de/myths-about-urandom/ practically] [http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ always] [https://www.mail-archive.com/cryptography@randombit.net/msg04748.html better]. However {{ic|/dev/random}} can be used for key generation in an entropy-starved situation (e.g. automatic installation on an embedded device without network and other entropy sources).<br />
|-<br />
! scope="row" style="text-align:right" | --verify-passphrase, -y<br />
| Yes<br />
| -<br />
| Default only for luksFormat and luksAddKey. No need to type for Arch Linux with LUKS mode at the moment. <br />
|}<br />
<br />
=== Encryption options for plain mode ===<br />
In dm-crypt ''plain'' mode, there is no master-key on the device, hence, there is no need to set it up. Instead the encryption options to be employed are used directly to create the mapping between an encrypted disk and a named device. The mapping can be created against a partition or a full device. In the latter case not even a partition table is needed. <br />
<br />
To create a ''plain'' mode mapping with cryptsetup's default parameters: <br />
# cryptsetup <options> open --type plain <device> <dmname><br />
Executing it will prompt for a password, which should have very high entropy. <br />
Below a comparison of default parameters with the example in [[Dm-crypt/Encrypting an entire system#Plain dm-crypt]]<br />
<br />
{| class="wikitable"<br />
! Option !! Cryptsetup 1.7.0 defaults !! Example !! Comment<br />
|-<br />
| '''--hash''' || {{ic|ripemd160}} || - || The hash is used to create the key from the passphrase; it is not used on a keyfile. <br />
|-<br />
| '''--cipher'''|| {{ic|aes-cbc-essiv:sha256}}|| {{ic|twofish-xts-plain64}} || The cipher consists of three parts: cipher-chainmode-IV generator. Please see [[Disk encryption#Ciphers and modes of operation]] for an explanation of these settings, and the [https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt DMCrypt documentation] for some of the options available. <br />
|-<br />
| '''--key-size'''||{{ic|256}}||{{ic|512}}||The key size (in bits). The size will depend on the cipher being used and also the chainmode in use. Xts mode requires twice the key size of cbc. <br />
|-<br />
| '''--offset'''||{{ic|0}}||{{ic|0}}||The offset from the beginning of the target disk from which to start the mapping<br />
|-<br />
| '''--key-file'''||default uses a passphrase||{{ic|/dev/sd''Z''}} (or e.g. /boot/keyfile.enc)||The device or file to be used as a key. See [[#Keyfiles]] for further details.<br />
|-<br />
| '''--keyfile-offset'''||{{ic|0}}||{{ic|0}}||Offset from the beginning of the file where the key starts (in bytes). This option is supported from ''cryptsetup'' 1.6.7 onwards. <br />
|-<br />
| '''--keyfile-size'''||{{ic|8192kB}}||- (default applies)||Limits the bytes read from the key file. This option is supported from ''cryptsetup'' 1.6.7 onwards. <br />
|}<br />
<br />
Using the device {{ic|/dev/sd''X''}}, the above right column example results in:<br />
{{bc|<nowiki># cryptsetup --cipher=twofish-xts-plain64 --offset=0 --key-file=</nowiki>/dev/sd''Z'' <nowiki>--key-size=512 open --type=plain /dev/sdX enc</nowiki>}}<br />
Unlike encrypting with LUKS, the above command must be executed ''in full'' whenever the mapping needs to be re-established, so it is important to remember the cipher, hash and key file details.<br />
We can now check that the mapping has been made:<br />
# fdisk -l<br />
An entry should now exist for {{ic|/dev/mapper/enc}}.<br />
<br />
== Encrypting devices with cryptsetup ==<br />
This section shows how to employ the options for creating new encrypted blockdevices and accessing them manually. <br />
<br />
=== Encrypting devices with LUKS mode ===<br />
==== Formatting LUKS partitions ====<br />
<br />
In order to setup a partition as an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup -c <cipher> -y -s <key size> luksFormat /dev/<partition name>|<br />
Enter passphrase: <password><br />
Verify passphrase: <password>}}<br />
first to setup the encrypted master-key. Checking results can be done with:<br />
# cryptsetup luksDump /dev/<drive><br />
<br />
This should be repeated for all partitions to be encrypted (except for {{ic|/boot}}). You will note that the dump not only shows the cipher header information, but also the key-slots in use for the LUKS partition. <br />
<br />
The following example will create an encrypted root partition using the default AES cipher in XTS mode with an effective 256-bit encryption <br />
{{bc|# cryptsetup -s 512 luksFormat /dev/sdaX}}<br />
<br />
=====Using LUKS to Format Partitions with a Keyfile=====<br />
<br />
When creating a new LUKS encrypted partition, a keyfile may be associated with the partition on its creation using:<br />
<br />
# cryptsetup -c <desired cipher> -s <key size> luksFormat /dev/<volume to encrypt> '''/path/to/mykeyfile'''<br />
<br />
This is accomplished by appending the bold area to the standard cryptsetup command which defines where the keyfile is located.<br />
<br />
See [[#Keyfiles]] for instructions on how to generate and manage keyfiles.<br />
<br />
====Unlocking/Mapping LUKS partitions with the device mapper ====<br />
<br />
Once the LUKS partitions have been created it is time to unlock them.<br />
<br />
The unlocking process will map the partitions to a new device name using the device mapper. This alerts the kernel that {{ic|/dev/<partition name>}} is actually an encrypted device and should be addressed through LUKS using the {{ic|/dev/mapper/<name>}} so as not to overwrite the encrypted data. To guard against accidental overwriting, read about the possibilities to [[Dm-crypt/Device encryption#Backup_and_restore|backup the cryptheader]] after finishing setup.<br />
<br />
In order to open an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup open --type luks /dev/<partition name> <device-mapper name>|<br />
Enter any LUKS passphrase: <password><br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
Usually the device mapped name is descriptive of the function of the partition that is mapped, example:<br />
<br />
# cryptsetup open --type luks /dev/sdaX root <br />
Once opened, the root partition device address would be {{ic|/dev/mapper/root}} instead of the partition (e.g. {{ic|/dev/sdaX}}). <br />
<br />
# cryptsetup open --type luks /dev/sda3 lvmpool <br />
For setting up LVM ontop the encryption layer the device file for the decrypted volume group would be anything like {{ic|/dev/mapper/lvmpool}} instead of {{ic|/dev/sdaX}}. LVM will then give additional names to all logical volumes created, e.g. {{ic|/dev/mapper/lvmpool-root}} and {{ic|/dev/mapper/lvmpool-swap}}.<br />
<br />
In order to write encrypted data into the partition it must be accessed through the device mapped name. The first step of access will typically be to create a filesystem <br />
# mkfs -t ext4 /dev/mapper/root<br />
and mount it <br />
# mount -t ext4 /dev/mapper/root /mnt<br />
The mounted blockdevice can then be used like any other partition. Once done, closing the device locks it again <br />
# umount /mnt<br />
# cryptsetup close root<br />
<br />
=== Encrypting devices with plain mode ===<br />
<br />
The creation and subsequent access of a ''dm-crypt'' plain mode encryption both require not more than using the ''cryptsetup'' {{ic|open}} action with correct [[Dm-crypt/Device encryption#Encryption_options_for_plain_mode|parameters]]. The following shows that with two examples of non-root devices, but adds a quirk by stacking both (i.e. the second is created inside the first). Obviously, stacking the encryption doubles overhead. The usecase here is simply to illustrate another example of the cipher option usage. <br />
<br />
A first mapper is created with ''cryptsetup's'' plain-mode defaults, as described in the table's left column above <br />
# cryptsetup --type plain -v open /dev/sdaX plain1 <br />
Enter passphrase: <br />
Command successful.<br />
# <br />
Now we add the second blockdevice inside it, using different encryption parameters and with an (optional) offset, create a filesystem and mount it <br />
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/mapper/plain1 plain2<br />
Enter passphrase: <br />
# lsblk -p <br />
NAME <br />
/dev/sda <br />
├─/dev/sdaX <br />
│ └─/dev/mapper/plain1 <br />
│ └─/dev/mapper/plain2 <br />
...<br />
# mkfs -t ext2 /dev/mapper/plain2<br />
# mount -t ext2 /dev/mapper/plain2 /mnt<br />
# echo "This is stacked. one passphrase per foot to shoot." > /mnt/stacked.txt<br />
We close the stack to check access works<br />
# cryptsetup close plain2<br />
# cryptsetup close plain1<br />
First, let's try to open the filesystem directly: <br />
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/sdaX plain2<br />
# mount -t ext2 /dev/mapper/plain2 /mnt<br />
mount: wrong fs type, bad option, bad superblock on /dev/mapper/plain2,<br />
missing codepage or helper program, or other error<br />
Why that did not work? Because the "plain2" starting block (10) is still encrypted with the cipher from "plain1". It can only be accessed via the stacked mapper. The error is arbitrary though, trying a wrong passphrase or wrong options will yield the same. For ''dm-crypt'' plain mode, the {{ic|open}} action will not error out itself. <br />
<br />
Trying again in correct order: <br />
# cryptsetup close plain2 # dysfunctional mapper from previous try<br />
# cryptsetup --type plain open /dev/sdaX plain1<br />
Enter passphrase: <br />
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/mapper/plain1 plain2 <br />
Enter passphrase: <br />
# mount /dev/mapper/plain2 /mnt && cat /mnt/stacked.txt<br />
This is stacked. one passphrase per foot to shoot.<br />
# exit<br />
''dm-crypt'' will handle stacked encryption with some mixed modes too. For example LUKS mode could be stacked on the "plain1" mapper. Its header would then be encrypted inside "plain1" when that is closed.<br />
<br />
Available for plain mode only is the option {{ic|--shared}}. With it a single device can be segmented into different non-overlapping mappers. We do that in the next example, using a ''loopaes'' compatible cipher mode for "plain2" this time: <br />
# cryptsetup --type plain --offset 0 --size 1000 open /dev/sdaX plain1 <br />
Enter passphrase: <br />
# cryptsetup --type plain --offset 1000 --size 1000 --shared --cipher=aes-cbc-lmk --hash=sha256 open /dev/sdaX plain2<br />
Enter passphrase: <br />
# lsblk -p<br />
NAME <br />
dev/sdaX <br />
├─/dev/sdaX <br />
│ ├─/dev/mapper/plain1 <br />
│ └─/dev/mapper/plain2 <br />
...<br />
As the devicetree shows both reside on the same level, i.e. are not stacked and "plain2" can be opened individually.<br />
<br />
== Cryptsetup actions specific for LUKS ==<br />
=== Key management ===<br />
It is possible to define up to 8 different keys per LUKS partition. This enables the user to create access keys for save backup storage: In a so-called key escrow, one key is used for daily usage, another kept in escrow to gain access to the partition in case the daily passphrase is forgotten or a keyfile is lost/damaged. Also a different key-slot could be used to grant access to a partition to a user by issuing a second key and later revoking it again. <br />
<br />
Once an encrypted partition has been created, the initial keyslot 0 is created (if no other was specified manually). Additional keyslots are numbered from 1 to 7. Which keyslots are used can be seen by issuing <br />
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki>grep BLED|<br />
Key Slot 0: ENABLED<br />
Key Slot 1: ENABLED<br />
Key Slot 2: ENABLED<br />
Key Slot 3: DISABLED<br />
Key Slot 4: DISABLED<br />
Key Slot 5: DISABLED<br />
Key Slot 6: DISABLED<br />
Key Slot 7: DISABLED}}<br />
<br />
Where <device> is the volume containing the LUKS header. This and all the following commands in this section work on header backup files as well. <br />
<br />
==== Adding LUKS keys ====<br />
<br />
Adding new keyslots is accomplished using cryptsetup with the {{ic|luksAddKey}} action. For safety it will always, i.e. also for already unlocked devices, ask for a valid existing key ("any passphrase") before a new one may be entered:<br />
<br />
# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) <br />
Enter any passphrase:<br />
Enter new passphrase for key slot:<br />
Verify passphrase: <br />
<br />
If {{ic|/path/to/<additionalkeyfile>}} is given, cryptsetup will add a new keyslot for <additionalkeyfile>. Otherwise a new passphrase will be prompted for twice. For using an existing ''keyfile'' to authorize the action, the {{ic|--key-file}} or {{ic|-d}} option followed by the "old" <keyfile> will try to unlock all available keyfile keyslots:<br />
<br />
# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) -d /path/to/<keyfile><br />
<br />
If it is intended to use multiple keys and change or revoke them, the {{ic|--key-slot}} or {{ic|-S}} option may be used to specify the slot: <br />
# cryptsetup luksAddKey /dev/<device> -S 6 <br />
Enter any passphrase: <br />
Enter new passphrase for key slot: <br />
Verify passphrase:<br />
# cryptsetup luksDump /dev/sda8 |grep 'Slot 6'<br />
Key Slot 6: ENABLED<br />
<br />
To show an associated action in this example, we decide to change the key right away: <br />
# cryptsetup luksChangeKey /dev/<device> -S 6 <br />
Enter LUKS passphrase to be changed: <br />
Enter new LUKS passphrase: <br />
<br />
before continuing to remove it.<br />
<br />
==== Removing LUKS keys ====<br />
<br />
There are three different actions to remove keys from the header: <br />
*{{ic|luksRemoveKey}} is used to remove a key by specifying its passphrase/key-file. <br />
*{{ic|luksKillSlot}} may be used to remove a key from a specific key slot (using another key). Obviously, this is extremely useful if you have forgotten a passphrase, lost a key-file, or have no access to it. <br />
*{{ic|luksErase}} is used to quickly remove '''all''' active keys. <br />
{{warning|<br />
*All above actions can be used to irrevocably delete the last active key for an encrypted device! <br />
*The {{ic|luksErase}} command was added in version 1.6.4 to quickly nuke access to the device. This action '''will not''' prompt for a valid passphrase! It will not [[Dm-crypt/Drive_preparation#Wipe_LUKS_header|wipe the LUKS header]], but all keyslots at once and you will, therefore, not be able to regain access unless you have a valid backup of the LUKS header.}} <br />
<br />
For above warning it is good to know the key we want to '''keep''' is valid. An easy check is to unlock the device with the {{ic|-v}} option, which will specify which slot it occupies: <br />
{{bc|# cryptsetup -v open /dev/<device> testcrypt<br />
Enter passphrase for /dev/<device>: <br />
Key slot 1 unlocked.<br />
Command successful.}}<br />
<br />
Now we can remove the key added in the previous subsection using its passphrase: <br />
# cryptsetup luksRemoveKey /dev/<device><br />
Enter LUKS passphrase to be deleted: <br />
If we had used the same passphrase for two keyslots, the first slot would be wiped now. Only executing it again would remove the second one. <br />
<br />
Alternatively, we can specify the key slot: <br />
# cryptsetup luksKillSlot /dev/<device> 6<br />
Enter any remaining LUKS passphrase:<br />
<br />
Note that in both cases, no confirmation was required.<br />
# cryptsetup luksDump /dev/sda8 |grep 'Slot 6'<br />
Key Slot 6: DISABLED<br />
To re-iterate the warning above: If the same passphrase had been used for key slots 1 and 6, both would be gone now.<br />
<br />
=== Backup and restore ===<br />
If the header of a LUKS encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much as a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. A damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table.<br />
<br />
Therefore, having a backup of the header and storing it on another disk might be a good idea.<br />
<br />
'''Attention:''' Many people recommend NOT backing up the cryptheader, but even so it's a single point of failure!<br />
In short, the problem is that LUKS is not aware of the duplicated cryptheader, which contains the master key used to encrypt all files on the partition. Of course this master key is encrypted with your passphrases or keyfiles.<br />
But if one of those gets compromised and you want to revoke it you have to do this on all copies of the cryptheader!<br />
I.e. if someone obtains a copy of the cryptheader and one of your keys he can decrypt the master key and access all your data.<br />
Of course the same is true for all backups you create of partitions. So you decide if you are one of those paranoids brave enough to go without a backup for the sake of security or not. See also the [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#6-backup-and-data-recovery LUKS FAQ] for further details on this.<br />
<br />
==== Backup using cryptsetup ====<br />
Cryptsetup's {{ic|luksHeaderBackup}} action stores a binary backup of the LUKS header and keyslot area:<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /mnt/<backup>/<file>.img<br />
where <device> is the partition containing the LUKS volume.<br />
<br />
{{Tip|You can also back up the plaintext header into ramfs and encrypt it in example with gpg before writing to persistent backup storage by executing the following commands.}}<br />
{{bc|# mkdir /root/<tmp>/<br />
# mount ramfs /root/<tmp>/ -t ramfs<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /root/<tmp>/<file>.img<br />
# gpg2 --recipient <User ID> --encrypt /root/<tmp>/<file>.img <br />
# cp /root/<tmp>/<file>.img.gpg /mnt/<backup>/<br />
# umount /root/<tmp>}}<br />
{{Warning|Tmpfs can swap to harddisk if low on memory so it is not recommended here.}}<br />
<br />
==== Restore using cryptsetup ====<br />
<br />
{{Warning|Restoring the wrong header or restoring to an unencrypted partition will cause data loss! The action can not perform a check whether the header is actually the ''correct'' one for that particular device.}} <br />
<br />
In order to evade restoring a wrong header, you can ensure it does work by using it as a remote {{ic|--header}} first: <br />
<br />
# cryptsetup -v --header /mnt/<backup>/<file>.img open /dev/<device> test <br />
Key slot 0 unlocked.<br />
Command successful.<br />
# mount /dev/mapper/test /mnt/test && ls /mnt/test <br />
# umount /mnt/test <br />
# cryptsetup close test <br />
<br />
Now that the check succeeded, the restore may be performed: <br />
# cryptsetup luksHeaderRestore /dev/<device> --header-backup-file ./mnt/<backup>/<file>.img<br />
<br />
Now that all the keyslot areas are overwritten; only active keyslots from the backup file are available after issuing the command.<br />
<br />
==== Manual backup and restore ====<br />
The header always resides at the beginning of the device and a backup can be performed without access to ''cryptsetup'' as well. First you have to find out the payload offset of the crypted partition:<br />
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki> grep "Payload offset"|<br />
Payload offset: 4040}}<br />
Second check the sector size of the drive<br />
{{hc|# fdisk -l /dev/<device> <nowiki>|</nowiki>grep "Sector size"|Sector size (logical/physical): 512 bytes / 512 bytes}}<br />
<br />
Now that you know the values, you can backup the header with a simple dd command:<br />
# dd if=/dev/<device> of=/path/to/<file>.img bs=512 count=4040<br />
and store it safely.<br />
<br />
A restore can then be performed using the same values as when backing up:<br />
# dd if=./<file>.img of=/dev/<device> bs=512 count=4040<br />
<br />
=== Re-encrypting devices ===<br />
<br />
{{Expansion|Introduce ''cryptsetup-reencrypt''.|Talk:Dm-crypt/Specialties#Recommend TRIM on non-FDE SSDs.3F}}<br />
<br />
The {{Pkg|cryptsetup}} package features the ''cryptsetup-reencrypt'' tool. It can be used to convert an existing unencrypted filesystem to a LUKS encrypted one (option {{ic|--new}}) and permanently remove LUKS encryption ({{ic|--decrypt}}) from a device. As its name suggests it can also be used to re-encrypt an existing LUKS encrypted device. For re-encryption it is possible to change the [[#Encryption options for LUKS mode]]. ''cryptsetup-reencrypt'' actions can be performed to unmounted devices only. See {{ic|man cryptsetup-reencrypt}} for more information. <br />
<br />
One application of re-encryption may be to secure the data again after a passphrase or [[#Keyfiles|keyfile]] has been compromised ''and'' one cannot be certain that no copy of the LUKS header has been obtained. For example, if only a passphrase has been shoulder-surfed but no physical/logical access to the device happened, it would be enough to change the respective passphrase/key only ([[#Key management]]). <br />
<br />
{{Warning|The tool has been available and improved since 2012, but it is still marked '''experimental'''. Always make sure a '''reliable backup''' is available before using it!}}<br />
<br />
The following shows an example to encrypt an unencrypted filesystem partition and a re-encryption of an existing LUKS device. <br />
<br />
==== Encrypt an unencrypted filesystem ====<br />
<br />
A LUKS encryption header is always stored at the beginning of the device. Since an existing filesystem will usually be allocated all partition sectors, the first step is to shrink it to make space for the LUKS header. <br />
<br />
The [[#Encryption_options_for_LUKS_mode|default]] LUKS header encryption cipher requires {{ic|4096}} 512-byte sectors. We already checked space and keep it simple by shrinking the existing {{ic|ext4}} filesystem on {{ic|/dev/sdaX}} to its current possible minimum: <br />
<br />
{{bc|# umount /mnt<br />
# e2fsck -f /dev/sdaX <br />
e2fsck 1.43-WIP (18-May-2015)<br />
Pass 1: Checking inodes, blocks, and sizes<br />
...<br />
/dev/sda6: 12/166320 files (0.0% non-contiguous), 28783/665062 blocks<br />
# resize2fs -M /dev/sdaX<br />
resize2fs 1.43-WIP (18-May-2015)<br />
Resizing the filesystem on /dev/sdaX to 26347 (4k) blocks.<br />
The filesystem on /dev/sdaX is now 26347 (4k) blocks long.}}<br />
<br />
Now we encrypt it, using the default cipher we do not have to specify it explicitly. Note there is no option (yet) to double-check the passphrase before encryption starts, be careful not to mistype: <br />
<br />
{{hc|# cryptsetup-reencrypt /dev/sdaX --new --reduce-device-size 4096S|<br />
WARNING: this is experimental code, it can completely break your data.<br />
Enter new passphrase: <br />
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed 37,6 MiB/s}}<br />
<br />
After it finished, the encryption was performed to the full partition, i.e. not only the space the filesystem was shrunk to ({{ic|sdaX}} has {{ic|2.6GiB}} and the CPU used in the example has no hardware AES instructions). As a final step we extend the filesystem of the now encrypted device again to occupy available space: <br />
<br />
{{bc|# cryptsetup open /dev/sdaX recrypt <br />
Enter passphrase for /dev/sdaX: <br />
...<br />
# resize2fs /dev/mapper/recrypt <br />
resize2fs 1.43-WIP (18-May-2015)<br />
Resizing the filesystem on /dev/mapper/recrypt to 664807 (4k) blocks.<br />
The filesystem on /dev/mapper/recrypt is now 664807 (4k) blocks long.<br />
# mount /dev/mapper/recrypt /mnt}}<br />
<br />
and are done.<br />
<br />
==== Re-encrypting an existing LUKS partition ====<br />
<br />
In this example an existing LUKS device is re-encrypted. <br />
<br />
{{Warning|Double-check you specify encryption options for ''cryptsetup-reencrypt'' correctly and ''never'' re-encrypt without a '''reliable backup'''! As of September 2015 the tool '''does''' accept invalid options and damage the LUKS header, if not used correctly!}}<br />
<br />
In order to re-encrypt a device with its existing encryption options, they do not need to be specified. A simple: <br />
<br />
{{hc|# cryptsetup-reencrypt /dev/sdaX| <br />
WARNING: this is experimental code, it can completely break your data.<br />
Enter passphrase for key slot 0: <br />
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed 36,5 MiB/s}}<br />
<br />
performs it. <br />
<br />
A possible usecase is to re-encrypt LUKS devices which have non-current encryption options. Apart from above warning on specifying options correctly, the ability to change the LUKS header may also be limited by its size. For example, if the device was initially encrypted using a CBC mode cipher and 128 bit key-size, the LUKS header will be half the size of above mentioned {{ic|4096}} sectors: <br />
{{hc|# cryptsetup luksDump /dev/sdaX <nowiki>|</nowiki>grep -e "mode" -e "Payload" -e "MK bits"|<br />
Cipher mode: cbc-essiv:sha256<br />
Payload offset: '''2048'''<br />
MK bits: 128}}<br />
While it is possible to upgrade the encryption of such a device, it is currently only feasible in two steps. First, re-encrypting with the same encryption options, but using the {{ic|--reduce-device-size}} option to make further space for the larger LUKS header. Second, re-encypt the whole device again with the desired cipher. For this reason and the fact that a backup should be created in any case, creating a new, fresh encrypted device to restore into is always the faster option.<br />
<br />
== Keyfiles ==<br />
<br />
{{Note|This section describes using a plaintext keyfile. If you want to encrypt your keyfile giving you two factor authentication see [[Dm-crypt/Specialties#Using_GPG_or_OpenSSL_Encrypted_Keyfiles|Using GPG or OpenSSL Encrypted Keyfiles]] for details, but please still read this section.}}<br />
<br />
'''What is a keyfile?'''<br />
<br />
A keyfile is a file whose data is used as the passphrase to unlock an encrypted volume.<br />
That means if such a file is lost or changed, decrypting the volume may no longer be possible.<br />
<br />
{{Tip|Define a passphrase in addition to the keyfile for backup access to encrypted volumes in the event the defined keyfile is lost or changed.}}<br />
<br />
'''Why use a keyfile?'''<br />
<br />
There are many kinds of keyfiles. Each type of keyfile used has benefits and disadvantages summarized below:<br />
<br />
=== Types of keyfiles ===<br />
==== passphrase ====<br />
<br />
This is a keyfile containing a simple passphrase. The benefit of this type of keyfile is that if the file is lost the data it contained is known and hopefully easily remembered by the owner of the encrypted volume. However the disadvantage is that this does not add any security over entering a passphrase during the initial system start.<br />
<br />
Example: 1234<br />
<br />
==== randomtext ====<br />
<br />
This is a keyfile containing a block of random characters. The benefit of this type of keyfile is that it is much more resistant to dictionary attacks than a simple passphrase. An additional strength of keyfiles can be utilized in this situation which is the length of data used. Since this is not a string meant to be memorized by a person for entry, it is trivial to create files containing thousands of random characters as the key. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase.<br />
<br />
Example: fjqweifj830149-57 819y4my1-38t1934yt8-91m 34co3;t8y;9p3y-<br />
<br />
==== binary ====<br />
<br />
This is a binary file that has been defined as a keyfile. When identifying files as candidates for a keyfile, it is recommended to choose files that are relatively static such as photos, music, video clips. The benefit of these files is that they serve a dual function which can make them harder to identify as keyfiles. Instead of having a text file with a large amount of random text, the keyfile would look like a regular image file or music clip to the casual observer. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase. Additionally, there is a theoretical loss of randomness when compared to a randomly generated text file. This is due to the fact that images, videos and music have some intrinsic relationship between neighboring bits of data that does not exist for a text file. However this is controversial and has never been exploited publicly.<br />
<br />
Example: images, text, video, ...<br />
<br />
=== Creating a keyfile with random characters ===<br />
<br />
==== Storing the keyfile on a filesystem ====<br />
<br />
A keyfile can be of arbitrary content and size. <br />
<br />
Here {{ic|dd}} is used to generate a keyfile of 2048 random bytes, storing it in the file {{ic|/etc/mykeyfile}}:<br />
<br />
# dd bs=512 count=4 if=/dev/urandom of=/etc/mykeyfile iflag=fullblock<br />
<br />
If you are planning to store the keyfile on an external device, you can also simply change the outputfile to the corresponding directory:<br />
<br />
# dd bs=512 count=4 if=/dev/urandom of=/media/usbstick/mykeyfile iflag=fullblock<br />
<br />
===== Securely overwriting stored keyfiles =====<br />
<br />
If you stored your temporary keyfile on a physical storage device, and want to delete it, remember to not just remove the keyfile later on, but use something like<br />
<br />
# shred --remove --zero mykeyfile<br />
<br />
to securely overwrite it. For overaged filesystems like FAT or ext2 this will suffice while in the case of journaling filesystems, flash memory hardware and other cases it is highly recommended to [[Securely wipe disk|wipe the entire device]] or at least the keyfiles partition.<br />
<br />
==== Storing the keyfile in tmpfs ====<br />
<br />
Alternatively, you can mount a tmpfs for storing the keyfile temporarily:<br />
<br />
# mkdir mytmpfs<br />
# mount tmpfs mytmpfs -t tmpfs -o size=32m<br />
# cd mytmpfs<br />
<br />
The advantage is that it resides in RAM and not on a physical disk, therefore it can not be recovered after unmounting the tmpfs. On the other hand this requires you to copy the keyfile to another filesystem you consider secure before unmounting.<br />
<br />
=== Configuring LUKS to make use of the keyfile ===<br />
<br />
Add a keyslot for the keyfile to the LUKS header:<br />
<br />
{{hc|# cryptsetup luksAddKey /dev/sda2 mykeyfile|<br />
Enter any LUKS passphrase:<br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
=== Unlocking a secondary partition at boot ===<br />
<br />
If the keyfile for a secondary file system is itself stored inside an encrypted root, it is safe while the system is powered off but can be sourced to automatically unlock the mount during with boot via [[Dm-crypt/System configuration#crypttab|crypttab]]. Following above first example <br />
{{hc|/etc/crypttab|home /dev/sda2 /etc/mykeyfile}}<br />
is all needed for unlocking, and <br />
{{hc|/etc/fstab|/dev/mapper/home /home ext4 defaults 0 2}} for mounting the LUKS blockdevice with the generated keyfile.<br />
{{Tip|If you prefer to use a {{ic|--plain}} mode blockdevice, the encryption options necessary to unlock it are specified in {{ic|/etc/crypttab}}. Take care to apply the systemd workaround mentioned in [[Dm-crypt/System configuration#crypttab|crypttab]] in this case.}}<br />
<br />
=== Unlocking the root partition at boot ===<br />
<br />
This is simply a matter of configuring [[mkinitcpio]] to include the necessary modules or files and configuring the [[Dm-crypt/System_configuration#cryptkey|cryptkey]] [[Kernel_parameters|kernel parameter]] to know where to find the keyfile.<br />
<br />
Two cases will be covered:<br />
<br />
# Using a keyfile stored on an external media (here a USB stick)<br />
# Using a keyfile embedded in the initramfs <br />
<br />
==== With a keyfile stored on an external media ====<br />
<br />
===== Configuring mkinitcpio =====<br />
<br />
You have to add two extra modules in your {{ic|/etc/mkinitcpio.conf}}, one for the drive's file system ({{ic|vfat}} module in the example below) and one for the codepage ({{ic|nls_cp437}} module) :<br />
MODULES="nls_cp437 vfat"<br />
<br />
In this example it is assumed that you use a FAT formatted USB drive ({{ic|vfat}} module). Replace those module names if you use another file system on your USB stick (e.g. {{ic|ext2}}) or another codepage. Users running the stock Arch kernel should stick to the codepage mentioned here. If it complains of bad superblock and bad codepage at boot, then you need an extra codepage module to be loaded. For instance, you may need {{ic|nls_iso8859-1}} module for {{ic|iso8859-1}} codepage.<br />
<br />
If you have a non-US keyboard, it might prove useful to load your keyboard layout before you are prompted to enter the password to unlock the root partition at boot. For this, you will need the {{ic|keymap}} hook before {{ic|encrypt}}.<br />
<br />
Generate a new initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
===== Configuring the kernel parameters =====<br />
<br />
Add the following options to the [[kernel parameters]]:<br />
<br />
cryptdevice=/dev/''<partition1>'':root cryptkey=/dev/''<partition2>'':<fstype>:<path><br />
<br />
For example:<br />
<br />
cryptdevice=/dev/sda3:root cryptkey=/dev/sdb1:vfat:/keys/secretkey<br />
<br />
Choosing a plain filename for your key provides a bit of 'security through obscurity'. The keyfile can not be a hidden file, that means the filename must not start with a dot, or the {{ic|encrypt}} hook will fail to find the keyfile during the boot process.<br />
<br />
The naming of device nodes like {{ic|/dev/sdb1}} is not guaranteed to stay the same across reboots. It is more reliable to access the device with udev's [[persistent block device naming]] instead. To assure that the {{ic|encrypt}} hook finds your keyfile when reading it from an external storage device, persistent block device names must be used. See the article [[persistent block device naming]].<br />
<br />
==== With a keyfile embedded in the initramfs ====<br />
<br />
{{Warning|Use an embedded keyfile '''only''' if you have some form of authentication mechanism beforehand that protects the keyfile sufficiently. Otherwise auto-decryption will occur, defeating completely the purpose of block device encryption.}}<br />
<br />
This method allows to use a specially named keyfile that will be embedded in the [[initramfs]] and picked up by the {{ic|encrypt}} [[Mkinitcpio#HOOKS|hook]] to unlock the root filesystem automatically. It may be useful to apply when using the [[GRUB#Boot partition|GRUB early cryptodisk]] feature, in order to avoid entering two passphrases during boot.<br />
<br />
By default the {{ic|encrypt}} hook takes the file specified in the {{ic|cryptkey}} kernel parameter and use it to unlock {{ic|cryptdevice}}. However, the code defaults to use {{ic|/crypto_keyfile.bin}} if it exists.[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/encrypt_hook?h=packages/cryptsetup#n8] If the initramfs contains a valid key with this name, decryption will occur automatically without the need to configure the {{ic|cryptkey}} parameter.<br />
<br />
[[#Creating_a_keyfile_with_random_characters|Generate the keyfile]], give it suitable permissions and [[#Adding_LUKS_keys|add it as a LUKS key]]:<br />
<br />
# dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin<br />
# chmod 000 /crypto_keyfile.bin<br />
# chmod 600 /boot/initramfs-linux*<br />
# cryptsetup luksAddKey /dev/sdX# /crypto_keyfile.bin<br />
<br />
{{Warning|When initramfs' permissions are set to 644 (by default), then all users will be able to dump the keyfile. Make sure the permissions are still 600 if you install a new kernel.}}<br />
<br />
Include the key in [[Mkinitcpio#BINARIES_and_FILES|mkinitcpio FILES array]]:<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=FILES="/crypto_keyfile.bin"}}<br />
<br />
Finally [[Mkinitcpio#Image_creation_and_activation|Regenerate your initramfs]].<br />
<br />
On the next reboot you should only have to enter your container decryption passphrase once.<br />
<br />
([http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/#bonus-login-once source])</div>Chehrihttps://wiki.archlinux.org/index.php?title=Wayland&diff=409962Wayland2015-11-23T17:29:15Z<p>Chehri: qt5-wayland is required.</p>
<hr />
<div>[[Category:X server]]<br />
[[es:Wayland]]<br />
[[fr:Wayland]]<br />
[[ja:Wayland]]<br />
[[ru:Wayland]]<br />
[[zh-CN:Wayland]]<br />
{{Related articles start}}<br />
{{Related|KMS}}<br />
{{Related|Xorg}}<br />
{{Related|Mir}}<br />
{{Related articles end}}<br />
'''Wayland''' is a new windowing protocol for Linux. Utilization of Wayland requires changes to and re-installation of parts of your system's software. For more information on Wayland see its [http://wayland.freedesktop.org/ homepage].<br />
<br />
== Requirements ==<br />
<br />
Currently Wayland will only work on systems utilizing [[KMS]].<br />
<br />
== Installation ==<br />
{{Note|Wayland is most likely installed on your system already, as it is an indirect dependency of {{Pkg|gtk2}} and {{Pkg|gtk3}}.}}<br />
<br />
[[Install]] the {{Pkg|wayland}} package.<br />
<br />
== Usage ==<br />
<br />
As Wayland is only a library, it is useless on its own. To replace X Server, you need a compositor (like Weston).<br />
<br />
== Weston ==<br />
<br />
=== Installation ===<br />
<br />
[[Install]] the {{Pkg|weston}} package.<br />
<br />
=== Usage ===<br />
<br />
{| class="wikitable" style="float: right; width: 200px;"<br />
|+ '''''Keyboard Shortcuts''' (super = windows key - can be changed, see weston.ini)'' {{Ic|Ctrl-b}}<br />
!Cmd<br />
!Action<br />
|-<br />
|Ctrl + Alt + Backspace<br />
|Quit Weston<br />
|-<br />
|Super + Scroll (or PageUp/PageDown)<br />
|Zoom in/out of desktop<br />
|-<br />
|Super + Tab<br />
|Switch windows<br />
|-<br />
|Super + LMB<br />
|Move Window<br />
|-<br />
|Super + MMB<br />
|Resize Window<br />
|-<br />
|Super + RMB<br />
|Rotate Window !<br />
|-<br />
|Super + Alt + Scroll<br />
|Change window opacity<br />
|-<br />
|Super + K<br />
|Force Kill Active Window<br />
|-<br />
|Super + KeyUp/KeyDown<br />
|Switch Prev/Next Workspace<br />
|-<br />
|Super + Shift + KeyUp/KeyDown<br />
|Grab Current Window and Switch Workspace<br />
|-<br />
|Super + F'''''n'''''<br />
|Switch to Workspace '''''n'''''<br />
|-<br />
|Super + S<br />
|Take a screenshot<br />
|-<br />
|Super + R<br />
|Record a screencast.<br />
|}<br />
<br />
Now that Wayland and its requirements are installed you should be ready to test it out. <br />
<br />
It is possible to run Weston inside a running X session:<br />
$ weston<br />
<br />
Alternatively, to try to launch Weston natively, switch to a terminal and run:<br />
$ weston-launch<br />
<br />
Then at a TTY within Weston, you can run the demos. To launch a terminal emulator:<br />
$ weston-terminal<br />
<br />
To move flowers around the screen:<br />
$ weston-flower <br />
<br />
To test the frame protocol (runs {{ic|glxgears}}):<br />
$ weston-gears<br />
<br />
To display images:<br />
$ weston-image image1.jpg image2.jpg...<br />
<br />
=== Configuration ===<br />
Example configuration file for keyboard layout, module selection and UI modifications. See {{ic|man weston.ini}} for full details:<br />
{{hc|~/.config/weston.ini|<br />
<nowiki>[core]<br />
### uncomment this line for xwayland support ###<br />
#modules=xwayland.so<br />
<br />
[shell]<br />
background-image=/usr/share/backgrounds/gnome/Aqua.jpg<br />
background-color=0xff002244<br />
panel-color=0x90ff0000<br />
locking=true<br />
animation=zoom<br />
#binding-modifier=ctrl<br />
#num-workspaces=6<br />
### for cursor themes install xcursor-themes pkg from Extra. ###<br />
#cursor-theme=whiteglass<br />
#cursor-size=24<br />
<br />
### tablet options ###<br />
#lockscreen-icon=/usr/share/icons/gnome/256x256/actions/lock.png<br />
#lockscreen=/usr/share/backgrounds/gnome/Garden.jpg<br />
#homescreen=/usr/share/backgrounds/gnome/Blinds.jpg<br />
#animation=fade<br />
<br />
[keyboard]<br />
keymap_rules=evdev<br />
#keymap_layout=gb<br />
#keymap_options=caps:ctrl_modifier,shift:both_capslock_cancel<br />
### keymap_options from /usr/share/X11/xkb/rules/base.lst ###<br />
<br />
<br />
[terminal]<br />
#font=DroidSansMono<br />
#font-size=14<br />
<br />
<br />
<br />
[launcher]<br />
icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png<br />
path=/usr/bin/gnome-terminal<br />
<br />
[launcher]<br />
icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png<br />
path=/usr/bin/weston-terminal<br />
<br />
[launcher]<br />
icon=/usr/share/icons/hicolor/24x24/apps/firefox.png<br />
path=/usr/bin/firefox<br />
<br />
[launcher]<br />
icon=/usr/share/icons/gnome/24x24/apps/arts.png<br />
path=./clients/flower<br />
<br />
[screensaver]<br />
# Uncomment path to disable screensaver<br />
path=/usr/libexec/weston-screensaver<br />
duration=600<br />
<br />
[input-method]<br />
path=/usr/libexec/weston-keyboard<br />
<br />
### for Laptop displays ###<br />
#[output]<br />
#name=LVDS1<br />
#mode=1680x1050<br />
#transform=90<br />
<br />
#[output]<br />
#name=VGA1<br />
# The following sets the mode with a modeline, you can get modelines for your preffered resolutions using the cvt utility<br />
#mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync<br />
#transform=flipped<br />
<br />
#[output]<br />
#name=X1<br />
#mode=1024x768<br />
#transform=flipped-270</nowiki><br />
}}<br />
<br />
Minimal {{ic|weston.ini}} :<br />
{{hc|~/.config/weston.ini|<br />
<nowiki>[core]<br />
modules=xwayland.so<br />
<br />
[keyboard]<br />
keymap_layout=gb<br />
<br />
[launcher]<br />
icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png<br />
path=/usr/bin/weston-terminal<br />
<br />
[launcher]<br />
icon=/usr/share/icons/hicolor/24x24/apps/firefox.png<br />
path=/usr/bin/firefox<br />
<br />
<br />
[output]<br />
name=LVDS1<br />
mode=1680x1050<br />
transform=90</nowiki><br />
}}<br />
<br />
==== XWayland ====<br />
[[Install]] the {{Pkg|xorg-server-xwayland}} package.<br />
<br />
When you want to run an X application from within Weston, it spins up Xwayland to service the request. The following configuration is shown above:<br />
<br />
{{hc|~/.config/weston.ini|<br />
<nowiki>[core]<br />
modules=xwayland.so</nowiki><br />
}}<br />
<br />
==== Screencast recording ====<br />
Weston has build-in screencast recording which can be started and stopped by pressing the {{ic|Super+r}} key combination. Screencasts are saved to the file {{ic|capture.wcap}} in the current working directory of Weston. <br />
<br />
The WCAP format is a lossless video format specific to Weston, which only records the difference in frames. To be able to play the recorded screencast, the WCAP file will need to be converted to a format which a media player can understand. First, convert the capture to the YUV pixel format:<br />
<br />
$ wcap-decode capture.wcap --yuv4mpeg2 > capture.y4m<br />
<br />
The YUV file can then be transcoded to other formats using [[FFmpeg]].<br />
<br />
==== High DPI displays ====<br />
<br />
For [[wikipedia:Retina_Display|Retina]] or [[HiDPI]] displays, use:<br />
<br />
{{hc|~/.config/weston.ini|<br />
<nowiki>[output]<br />
name=...<br />
scale=2</nowiki><br />
}}<br />
<br />
==== Shell font ====<br />
<br />
Weston uses the default sans-serif font for window title bars, clocks, etc. See [[Font configuration#Replace or set default fonts]] for instructions on how to change this font.<br />
<br />
== GUI libraries ==<br />
<br />
See details on the [http://wayland.freedesktop.org/toolkits.html official website].<br />
<br />
=== GTK+ 3 ===<br />
<br />
The {{Pkg|gtk3}} package from the official repositories now has the Wayland backend enabled.<br />
<br />
GTK+ 3 gained support for multiple backends at runtime and can switch between backends in the same way Qt can with lighthouse.<br />
<br />
When both Wayland and X backends are enabled, GTK+ will default to the X11 backend, but this can be overridden by modifying an environment variable: {{ic|GDK_BACKEND&#61;wayland}}.<br />
<br />
=== Qt 5 ===<br />
The {{Grp|qt5}} package from the repositories has the Wayland support if {{Pkg|qt5-wayland}} is installed. <br />
To run a Qt 5 app with the Wayland plugin, set the {{ic|1=QT_QPA_PLATFORM=wayland-egl}} [[environment variable]].<br />
<br />
=== Clutter ===<br />
<br />
The Clutter toolkit has a Wayland backend that allows it to run as a Wayland client. The backend is enabled in the official package in extra.<br />
<br />
To run a Clutter app on Wayland, set {{ic|CLUTTER_BACKEND&#61;wayland}}.<br />
<br />
=== SDL ===<br />
<br />
Experimental wayland support is now in SDL 2.0.2 and enabled by default on Arch Linux.<br />
<br />
To run a SDL application on Wayland, set {{ic|SDL_VIDEODRIVER&#61;wayland}}.<br />
<br />
=== GLFW ===<br />
<br />
Experimental wayland support is now in GLFW 3.1 and can be enabled with the {{ic|-DGLFW_USE_WAYLAND&#61;ON}} CMake option at compile time. You can also install the package {{AUR|glfw-wayland-git}} from the AUR.<br />
<br />
=== EFL ===<br />
<br />
EFL has complete Wayland support. <br />
To run a EFL application on Wayland, see Wayland [http://wayland.freedesktop.org/efl.html project page].<br />
<br />
== Window managers and desktop shells ==<br />
<br />
{| class="wikitable"<br />
! Name<br />
! Type<br />
! Description<br />
|-<br />
| GNOME<br />
| Compositing<br />
| See [[GNOME#Starting GNOME]].<br />
|-<br />
| Hawaii<br />
| ''(Unclear)''<br />
| See [[Hawaii]].<br />
|-<br />
| sway<br />
| Tiling<br />
| [https://github.com/SirCmpwn/sway Sway] is an i3-compatible window manager for Wayland.<br />
|-<br />
| KDE<br />
| Compositing<br />
| [[KDE]] 4.11 added support for [http://blog.martin-graesslin.com/blog/2013/06/starting-a-full-kde-plasma-session-in-wayland/ KWin under Wayland system compositor]. With [https://community.kde.org/KWin/Wayland#Start_a_Plasma_session_on_Wayland KDE Plasma 5.4], the first technology preview of a Wayland session is released but it is currently targeted for the mobile platform and does not yet allow to use it as a full replacement for Xorg based desktop.<br />
|-<br />
| Orbment<br />
| Tiling<br />
| [https://github.com/Cloudef/orbment orbment] (previously loliwm) is a tiling WM for Wayland.<br />
|-<br />
| Velox<br />
| Tiling<br />
| [https://github.com/michaelforney/velox velox] is a simple window manager based on swc. It is inspired by [[dwm]] and [[xmonad]].<br />
|-<br />
| Orbital<br />
| Compositing<br />
| [https://github.com/giucam/orbital Orbital] is a Wayland compositor and shell, using Qt5 and Weston. The goal of the project is to build a simple yet flexible and good looking Wayland desktop. It is not a full fledged DE but rather the analogue of a WM in the X11 world, such as [[Awesome]] or [[Fluxbox]].<br />
|-<br />
| Papyros Shell<br />
| ''(Unclear)''<br />
| [https://github.com/papyros/papyros-shell Papyros Shell] is the desktop shell for [http://papyros.io Papyros], built using QtQuick and QtCompositor as a compositor for Wayland.<br />
|-<br />
| Maynard<br />
| ''(Unclear)''<br />
| [https://github.com/raspberrypi/maynard Maynard] is a desktop shell client for Weston based on GTK. It was based on weston-gtk-shell, a project by Tiago Vignatti.<br />
|-<br />
| Motorcar<br />
| ''(Unclear)''<br />
| [https://github.com/evil0sheep/motorcar Motorcar] is a wayland compositor to explore 3D windowing.<br />
|}<br />
<br />
Some of installed wayland desktop clients might store information in {{ic|/usr/share/wayland-sessions/*.desktop}} files about how to start them in wayland.<br />
<br />
==Troubleshooting==<br />
<br />
=== LLVM assertion failure ===<br />
If you get an LLVM assertion failure, you need to rebuild {{Pkg|mesa}} without Gallium LLVM until this problem is fixed. <br />
<br />
This may imply disabling some drivers which require LLVM.<br />
You may also try exporting the following, if having problems with hardware drivers: <br />
<br />
$ export EGL_DRIVER=/usr/lib/egl/egl_gallium.so<br />
<br />
=== Weston fails to launch after update to 1.7 ===<br />
This is possibly caused by the {{ic|desktop-shell.so}} module being loaded by your {{ic|weston.ini}}. This used to be required, but is not anymore.<br />
<br />
Remove it from the {{ic|[core]}} section:<br />
<br />
{{hc|~/.config/weston.ini|<br />
<nowiki>[core]<br />
modules=xwayland.so,desktop-shell.so</nowiki><br />
}}<br />
<br />
So that you end up with:<br />
<br />
{{hc|~/.config/weston.ini|<br />
<nowiki>[core]<br />
modules=xwayland.so</nowiki><br />
}}<br />
<br />
== See also ==<br />
* [[Cursor themes]]<br />
* [https://bbs.archlinux.org/viewtopic.php?id=107499 Arch Linux forum discussion]<br />
* [http://wayland.freedesktop.org/docs/html/ Wayland documentation online]</div>Chehrihttps://wiki.archlinux.org/index.php?title=GnuPG&diff=409338GnuPG2015-11-16T02:36:23Z<p>Chehri: Changing the passphrase on subkeys seems broken.</p>
<hr />
<div>[[Category:Encryption]]<br />
[[es:GnuPG]]<br />
[[ja:GnuPG]]<br />
[[ru:GnuPG]]<br />
[http://www.gnupg.org GnuPG] allows to encrypt and sign your data and communication, features a versatile key management system as well as access modules for all kinds of public key directories.<br />
<br />
== Installation ==<br />
<br />
[[Install]] the {{Pkg|gnupg}} package.<br />
<br />
This will also install {{Pkg|pinentry}}, a collection of simple PIN or passphrase entry dialogs which GnuPG uses for passphrase entry. ''pinentry'' is determined by the symbolic link {{ic|/usr/bin/pinentry}}, which by default points to {{ic|/usr/bin/pinentry-gtk-2}}.<br />
<br />
== Environment variables ==<br />
<br />
=== GNUPGHOME ===<br />
<br />
{{ic|$GNUPGHOME}} is used by GnuPG to point to the directory where all configuration files are stored. By default {{ic|$GNUPGHOME}} is not set and your {{ic|$HOME}} is used instead, thus you will find a {{ic|~/.gnupg}} directory right after the install. You may change this default setting by putting this line in one of your regular [[startup files]]:<br />
<br />
export GNUPGHOME="''/path/to/directory''"<br />
<br />
{{Note|By default, the gnupg directory has its [[Permissions]] set to ''700'' and the files it contains have their permissions set to ''600''. Only the owner of the directory has permission to read, write and access the files (''r'',''w'',''x''). This is for security purposes and should not be changed. In case this directory or any file inside it does not follow this security measure, you will get warnings about unsafe file and home directory permissions.}}<br />
<br />
== Configuration file ==<br />
<br />
Default is {{ic|~/.gnupg/gpg.conf}}. If you want to change the default location, either run gpg this way {{ic|$ gpg --homedir ''path/to/file''}} or use {{ic|$GNUPGHOME}} variable.<br />
<br />
Append in this file any long options you want. Do not write the two dashes, but simply the name of the option and required arguments. You will find a skeleton file {{ic|/usr/share/gnupg/gpg-conf.skel}}.<br />
Following is a basic configuration file:<br />
{{hc|~/.gnupg/gpg.conf|<br />
default-key ''name'' # useful in case you manage several keys and want to set a default one<br />
keyring ''file'' # will add ''file'' to the current list of keyrings<br />
trustdb-name ''file'' # use ''file'' instead of the default trustdb<br />
homedir ''dir'' # set the name of the gnupg home dir to ''dir'' instead of ~/.gnupg<br />
display-charset utf-8 # bypass all translation and assume that the OS uses native UTF-8 encoding<br />
keyserver ''name'' # use ''name'' as your keyserver<br />
no-greeting # suppress the initial copyright message<br />
armor # create ASCII armored output. Default is binary OpenPGP format<br />
}}<br />
<br />
If you want to setup some default options for new users, put configuration files in {{ic|/etc/skel/.gnupg/}}. When the new user is added in system, files from here will be copied to its GnuPG home directory. There is also a simple script called ''addgnupghome'' which you can use to create new GnuPG home directories for existing users:<br />
<br />
# addgnupghome user1 user2<br />
<br />
This will add the respective {{ic|/home/user1/.gnupg}} and {{ic|/home/user2/.gnupg}} and copy the files from the skeleton directory to it. Users with existing GnuPG home directory are simply skipped.<br />
<br />
== Basic keys management ==<br />
<br />
{{Note|Whenever a ''{{ic|<user-id>}}'' is required in a command, it can be specified with your key ID, fingerprint, a part of your name or email address, etc. GnuPG is flexible on this.}}<br />
<br />
=== Create key ===<br />
<br />
Firstly, you may want to use stronger algorithms:<br />
<br />
{{hc|~/.gnupg/gpg.conf|<br />
...<br />
<br />
personal-digest-preferences SHA512<br />
cert-digest-algo SHA512<br />
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed<br />
personal-cipher-preferences TWOFISH CAMELLIA256 AES 3DES<br />
}}<br />
<br />
In the latest version of GnuPG, the default algorithms used are SHA256 and AES, both of which are secure enough for most people. However, if you are using a version of GnuPG older than 2.1, or if you want an even higher level of security, then you should follow the above step.<br />
<br />
Now generate a private key by typing in a terminal:<br />
<br />
$ gpg --full-gen-key<br />
<br />
{{Note|<br />
* The {{ic|--full-gen-key}} option is available since {{Pkg|gnupg}}-2.1.0.<br />
* You can use {{ic|--expert}} for getting alternative ciphers available (like [[wikipedia:Elliptic_curve_cryptography|ECC Elliptic Curve]]).<br />
}}<br />
<br />
You will be asked several questions. In general, most users will want both a RSA (sign only) and a RSA (encrypt only) key. A keysize of 2048 is sufficient. Using 4096 [https://www.gnupg.org/faq/gnupg-faq.html#no_default_of_rsa4096 "gives us almost nothing, while costing us quite a lot."]<br />
<br />
While having an expiration date for subkeys is not technically necessary, it is considered good practice. A period of a year is generally good enough for the average user. This way even if you lose access to your keyring, it will allow others to know that it is no longer valid. Note that you can extend the expiry date after key creation without having to re-issue a new key.<br />
<br />
=== Manage your key ===<br />
<br />
* Running the {{ic|gpg --edit-key ''<user-id>''}} command will present a menu which enables you to do most of your key management related tasks. Following is an example to set your expiration date:<br />
<br />
$ gpg --edit-key ''<user-id>''<br />
> key ''number''<br />
> expire ''yyyy-mm-dd''<br />
> save<br />
> quit<br />
<br />
Some useful commands:<br />
> passwd # change the passphrase<br />
> clean # compact any user ID that is no longer usable (e.g revoked or expired)<br />
> revkey # revoke a key<br />
> addkey # add a subkey to this key<br />
> expire # change the key expiration time<br />
<br />
{{Tip|If you have multiple email accounts you can add each one of them as an identity, using {{ic|adduid}} command. You can then set your favourite one as {{ic|primary}}.}}<br />
<br />
* Generate an ASCII version of your public key (e.g. to distribute it by e-mail):<br />
<br />
$ gpg --armor --output public.key --export ''<user-id>''<br />
<br />
* Register your key with a public PGP key server, so that others can retrieve your key without having to contact you directly:<br />
<br />
$ gpg --keyserver pgp.mit.edu --send-keys ''<key-id>''<br />
<br />
* Sign and encrypt for user Bob<br />
<br />
$ gpg -se -r Bob ''file''<br />
<br />
* make a clear text signature<br />
<br />
$ gpg --clearsign ''file''<br />
<br />
=== Exporting subkey ===<br />
<br />
{{out of date|gpg seems to complain about the master key missing when attempting to change the passphrase on a stripped subkey.}}<br />
<br />
If you plan to use the same key across multiple devices, you may want to strip out your master key and only keep the bare minimum encryption subkey on less secure systems.<br />
<br />
First, find out which subkey you want to export.<br />
<br />
$ gpg -K<br />
<br />
Select only that subkey to export.<br />
<br />
$ gpg -a --export-secret-subkeys [subkey id]! > /tmp/subkey.gpg<br />
<br />
{{Warning|If you forget to add the !, all of your subkeys will be exported.}}<br />
<br />
At this point you could stop, but it is most likely a good idea to change the passphrase as well. Import the key into a temporary folder. <br />
<br />
$ gpg --homedir /tmp/gpg --import /tmp/subkey.gpg<br />
$ gpg --homedir /tmp/gpg --edit-key ''<user-id>''<br />
> passwd<br />
> save<br />
$ gpg --homedir /tmp/gpg -a --export-secret-subkeys [subkey id]! > /tmp/subkey.altpass.gpg<br />
<br />
{{Note|You will get a warning that the master key was not available and the password was not changed, but that can safely be ignored as the subkey password was.}}<br />
<br />
At this point, you can now use {{ic|/tmp/subkey.altpass.gpg}} on your other devices.<br />
<br />
=== Rotating subkeys ===<br />
<br />
{{Warning|'''Never''' delete your expired or revoked subkeys unless you have a good reason. Doing so will cause you to lose the ability to decrypt files encrypted with the old subkey. Please '''only''' delete expired or revoked keys from other users to clean your keyring.}}<br />
<br />
If you have set your subkeys to expire after a set time, you can create new ones. Do this a few weeks in advance to allow others to update their keyring.<br />
<br />
{{Note|You do not need to create a new key simply because it is expired. You can extend the expiration date.}}<br />
<br />
* Create new subkey (repeat for both signing and encrypting key)<br />
<br />
$ gpg --edit-key ''<user-id>''<br />
> addkey<br />
<br />
And answer the following questions it asks (see previous section for suggested settings).<br />
<br />
* Save changes<br />
<br />
> save<br />
<br />
* Update it to a keyserver.<br />
<br />
$ gpg --keyserver pgp.mit.edu --send-keys ''<user-id>''<br />
<br />
{{Note|Revoking expired subkeys is unnecessary and arguably bad form. If you are constantly revoking keys, it may cause others to lack confidence in you.}}<br />
<br />
=== Import key ===<br />
<br />
* Import a public key to your public key ring:<br />
<br />
$ gpg --import public.key<br />
<br />
* Import a private key to your secret key ring:<br />
<br />
$ gpg --import private.key<br />
<br />
* Import key from a key server (if '--keyserver' is omitted, the default is used):<br />
<br />
$ gpg --keyserver pgp.mit.edu --recv-keys <keyid><br />
<br />
=== List keys ===<br />
<br />
* Keys in your public key ring:<br />
<br />
$ gpg --list-keys<br />
<br />
* Keys in your secret key ring:<br />
<br />
$ gpg --list-secret-keys<br />
<br />
== Encrypt and decrypt ==<br />
<br />
When encrypting or decrypting it is possible to have more than one private key in use. If this occurs you need to select the active key. This can be done by using the option {{ic|-u ''<user-id>''}} or by using the option {{ic|--local-user ''<user-id>''}}. This causes the default key to use to be replaced by wanted key.<br />
<br />
To encrypt a file, use:<br />
<br />
$ gpg --encrypt -o secret.tar.gpg secret.tar<br />
<br />
* If you want to change recipient this can be done by the option {{ic|-r ''<user-id>''}} (or {{ic|--recipient ''<user-id>''}}).<br />
* You can use gnupg to encrypt your sensitive documents, but only individual files at a time. If you want to encrypt directories or a whole file-system you should consider using [[TrueCrypt]] or [[EncFS]], though you can always tarball various files and then encrypt them.<br />
<br />
To decrypt a file, use:<br />
<br />
$ gpg --decrypt secret.tar.gpg<br />
<br />
You will be prompted to enter your passphrase.<br />
<br />
=== Encrypt a password ===<br />
<br />
It can be useful to encrypt some password, so it will not be written in clear on a configuration file. A good example is your email password.<br />
<br />
First create a file with your password. You '''need''' to leave '''one''' empty line after the password, otherwise gpg will return an error message when evaluating the file.<br />
<br />
Then run:<br />
<br />
$ gpg -e -a -r ''<user-id>'' ''your_password_file''<br />
<br />
{{ic|-e}} is for encrypt, {{ic|-a}} for armor (ASCII output), {{ic|-r}} for recipient user ID.<br />
<br />
You will be left with a new {{ic|''your_password_file''.asc}} file.<br />
<br />
== gpg-agent ==<br />
<br />
{{Out of date|[[#GPG_AGENT_INFO]] is deprecated since {{pkg|gnupg}}-2.1. See [[#Unattended passphrase]] for new method.}}<br />
<br />
''gpg-agent'' is mostly used as daemon to request and cache the password for the keychain. This is useful if GnuPG is used from an external program like a mail client. It can be activated by adding following line in {{ic|gpg.conf}}:<br />
<br />
{{hc|~/.gnupg/gpg.conf|use-agent}}<br />
<br />
This tells GnuPG to use the agent whenever it needs the password. However, the agent needs to be already running. To autostart it, add the following entry to your {{ic|.xinitrc}} or {{ic|.bash_profile}}. Remember to change the envfile path if you changed your {{ic|$GNUPGHOME}}.<br />
<br />
{{hc|~/.bash_profile|2=<nowiki><br />
envfile="$HOME/.gnupg/gpg-agent.env"<br />
if [[ -e "$envfile" ]] && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then<br />
eval "$(cat "$envfile")"<br />
else<br />
eval "$(gpg-agent --daemon --enable-ssh-support --write-env-file "$envfile")"<br />
fi<br />
export GPG_AGENT_INFO # the env file does not contain the export statement<br />
export SSH_AUTH_SOCK # enable gpg-agent for ssh<br />
</nowiki>}}<br />
<br />
Log out of the session and log back in. Check if ''gpg-agent'' is activated:<br />
<br />
$ pgrep gpg-agent<br />
<br />
=== Configuration ===<br />
<br />
gpg-agent can be configured via {{ic|~/.gnupg/gpg-agent.conf}} file. The configuration options are listed in {{ic|man gpg-agent}}. For example you can change cache ttl for unused keys:<br />
<br />
{{hc|~/.gnupg/gpg-agent.conf|<br />
default-cache-ttl 3600<br />
}}<br />
<br />
{{Tip|To cache your passphrase for the whole session, please run the following command:<br />
$ /usr/lib/gnupg/gpg-preset-passphrase --preset XXXXXX<br />
<br />
where XXXX is the keygrip. You can get its value when running {{ic|gpg --with-keygrip -K}}. Passphrase will be stored until {{ic|gpg-agent}} is restarted. If you set up {{ic|default-cache-ttl}} value, it will take precedence.<br />
}}<br />
<br />
=== Reload the agent ===<br />
<br />
After changing the configuration, reload the agent by piping the {{ic|RELOADAGENT}} string to {{ic|gpg-connect-agent}}.<br />
<br />
$ echo RELOADAGENT | gpg-connect-agent<br />
<br />
The shell should print {{ic|OK}}.<br />
<br />
=== pinentry ===<br />
<br />
Finally, the agent needs to know how to ask the user for the password. This can be set in the gpg-agent configuration file.<br />
<br />
The default uses a gtk dialog. There are other options - see {{ic|info pinentry}}. To change the dialog implementation set {{ic|pinentry-program}} configuration option:<br />
{{hc|~/.gnupg/gpg-agent.conf|<br />
<br />
# PIN entry program<br />
# pinentry-program /usr/bin/pinentry-curses<br />
# pinentry-program /usr/bin/pinentry-qt4<br />
# pinentry-program /usr/bin/pinentry-kwallet<br />
<br />
pinentry-program /usr/bin/pinentry-gtk-2<br />
}}<br />
<br />
{{Tip|For using {{ic|/usr/bin/pinentry-kwallet}} you have to install the {{Pkg|kwalletcli}} package.}}<br />
<br />
After making this change, reload the gpg-agent.<br />
<br />
=== Start gpg-agent with systemd user ===<br />
<br />
It is possible to use the [[Systemd/User]] facilities to start the agent.<br />
<br />
Create a systemd unit file:<br />
<br />
{{hc|~/.config/systemd/user/gpg-agent.service|2=<br />
[Unit]<br />
Description=GnuPG private key agent<br />
IgnoreOnIsolate=true<br />
<br />
[Service]<br />
Type=forking<br />
ExecStart=/usr/bin/gpg-agent --daemon --homedir=%h/.gnupg<br />
ExecStop=/usr/bin/pkill gpg-agent<br />
Restart=on-abort<br />
<br />
[Install]<br />
WantedBy=default.target<br />
}}<br />
<br />
{{Note|<br />
* You may need to set some environment variables for the service, for example {{ic|GNUPGHOME}}. See [[systemd/User#Environment variables]] for details.<br />
* if your gnupg home directory is ~/.gnupg, there is no need to specify its path<br />
* {{ic|gpg -agent}} will not use standard socket, but rather listen for a socket name {{ic|S.gpg-agent}} located in your gnupg home directory. We can thus forget any script to read an environment file and get the path of the random socket created in {{ic|/tmp}}.<br />
* If you use SSH capabilities of gpg-agent (--enable-ssh-support), the systemd unit above will not work<br />
}}<br />
<br />
{{Tip|<br />
To ensure your gpg-agent is running and listening to connection, simply run this command: {{ic|$ gpg-connect-agent}}. If your settings are valid, you will be on a prompt (enter ''bye'' and ''quit'' to close connection and leave)<br />
}}<br />
<br />
=== Unattended passphrase ===<br />
<br />
Starting with GnuPG 2.1.0 the use of gpg-agent and pinentry is required; this may break backwards compatibility for passphrases piped in from STDIN using the {{ic|--passphrase-fd 0}} commandline option. In order to have the same type of functionality as the older releases two things must be done:<br />
<br />
First, edit the gpg-agent configuration to allow ''loopback'' pinentry mode:<br />
<br />
{{hc|1=~/.gnupg/gpg-agent.conf|2=<br />
allow-loopback-pinentry<br />
}}<br />
<br />
Restart the gpg-agent process if it is running to let the change take effect.<br />
<br />
Second, either the application needs to be updated to include a commandline parameter to use loopback mode like so:<br />
<br />
$ gpg --pinentry-mode loopback ...<br />
<br />
...or if this is not possible, add the option to the configuration:<br />
<br />
{{hc|1=~/.gnupg/gpg.conf|2=<br />
pinentry-mode loopback<br />
}}<br />
<br />
{{Note|The upstream author indicates setting '''pinentry-mode loopback''' in ''gpg.conf'' may break other usage, using the commandline option should be preferred if at all possible. [https://bugs.g10code.com/gnupg/issue1772] }}<br />
<br />
== Keysigning parties ==<br />
<br />
To allow users to validate keys on the keyservers and in their keyrings (i.e. make sure they are from whom they claim to be), PGP/GPG uses a so-called "Web of Trust". There are many hacker events targeted to maintain this Web of Trust are held, including keysigning parties.<br />
<br />
The [[Wikipedia:Zimmermann–Sassaman key-signing protocol|Zimmermann-Sassaman]] key-signing protocol is a way of making these very effective. [http://www.cryptnet.net/fdp/crypto/keysigning_party/en/keysigning_party.html Here] you will find a how-to article.<br />
<br />
=== caff ===<br />
<br />
For an easier process of signing keys and sending signatures to the owners after a keysigning party, you can use the tool ''caff''. It can be installed from the AUR with the package {{AUR|caff-svn}} or bundled together with other useful tools in the package {{AUR|signing-party-svn}}.<br />
Either way, there will be a lot of dependencies installing from the AUR. Alternatively you can install them from CPAN with<br />
cpanm Any::Moose<br />
cpanm GnuPG::Interface<br />
<br />
To send the signatures to their owners you need a working [[Wikipedia:Message transfer agent|MTA]]. If you do not have already one, install [[msmtp]].<br />
<br />
== Smartcards ==<br />
<br />
{{Note|{{Pkg|pcsclite}} and {{Pkg|libusb-compat}} have to be installed, and the contained [[systemd#Using units|systemd]] service {{ic|pcscd.service}} has to be running.}}<br />
<br />
GnuPG uses ''scdaemon'' as an interface to your smartcard reader, please refer to the [[man page]] for details.<br />
<br />
=== GnuPG only setups ===<br />
<br />
If you do not plan to use other cards but those based on GnuPG, you should check the {{Ic|reader-port}} parameter in {{ic|~/.gnupg/scdaemon.conf}}. The value '0' refers to the first available serial port reader and a value of '32768' (default) refers to the first USB reader.<br />
<br />
=== GnuPG together with OpenSC ===<br />
<br />
If you are using any smartcard with an opensc driver (e.g.: ID cards from some countries) you should pay some attention to GnuPG configuration. Out of the box you might receive a message like this when using {{Ic|gpg --card-status}}<br />
<br />
gpg: selecting openpgp failed: ec=6.108<br />
<br />
By default, scdaemon will try to connect directly to the device. This connection will fail if the reader is being used by another process. For example: the pcscd daemon used by OpenSC. To cope with this situation we should use the same underlying driver as opensc so they can work well together. In order to point scdaemon to use pcscd you should remove {{Ic|reader-port}} from {{ic|~/.gnupg/scdaemon.conf}}, specify the location to {{ic|libpcsclite.so}} library and disable ccid so we make sure that we use pcscd:<br />
<br />
{{hc|~/.gnupg/scdaemon.conf|<nowiki><br />
pcsc-driver /usr/lib/libpcsclite.so<br />
card-timeout 5<br />
disable-ccid<br />
</nowiki>}}<br />
<br />
Please check {{Ic|man scdaemon}} if you do not use OpenSC.<br />
<br />
== Troubleshooting ==<br />
<br />
=== Not enough random bytes available ===<br />
When generating a key, gpg can run into this error:<br />
Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy!<br />
To check the available entropy, check the kernel parameters:<br />
cat /proc/sys/kernel/random/entropy_avail<br />
A healthy Linux system with a lot of entropy available will have return close to the full 4,096 bits of entropy. If the value returned is less than 200, the system is running low on entropy. <br />
<br />
To solve it, remember you do not often need to create keys and best just do what the message suggests (e.g. create disk activity, move the mouse, edit the wiki - all will create entropy). If that does not help, check which service is using up the entropy and consider stopping it for the time. If that is no alternative, see [[Random number generation#Faster alternatives]].<br />
<br />
=== su ===<br />
<br />
When using {{Ic|pinentry}}, you must have the proper permissions of the terminal device (e.g. {{Ic|/dev/tty1}}) in use. However, with ''su'' (or ''sudo''), the ownership stays with the original user, not the new one. This means that pinentry will fail, even as root. The fix is to change the permissions of the device at some point before the use of pinentry (i.e. using gpg with an agent). If doing gpg as root, simply change the ownership to root right before using gpg:<br />
<br />
chown root /dev/ttyN # where N is the current tty<br />
<br />
and then change it back after using gpg the first time. The equivalent is likely to be true with {{Ic|/dev/pts/}}.<br />
<br />
{{Note|The owner of tty ''must'' match with the user for which pinentry is running. Being part of the group {{Ic|tty}} '''is not''' enough.}}<br />
<br />
=== Agent complains end of file ===<br />
<br />
The default pinentry program is pinentry-gtk-2, which needs a DBus session bus to run properly. See [[General troubleshooting#Session permissions]] for details.<br />
<br />
Alternatively, you can use {{ic|pinentry-qt}}. See [[#pinentry]].<br />
<br />
=== KGpg configuration permissions ===<br />
<br />
There have been issues with {{Pkg|kdeutils-kgpg}} being able to access the {{ic|~/.gnupg/}} options. One issue might be a result of a deprecated ''options'' file, see the [https://bugs.kde.org/show_bug.cgi?id=290221 bug] report.<br />
<br />
Another user reported that ''KGpg'' failed to start until the {{ic|~/.gnupg}} folder is set to {{ic|drwxr-xr-x}} permissions. If you require this work-around, ensure that the directory contents retain {{ic|-rw-------}} permissions! Further, report it as a bug to the [https://bugs.kde.org/buglist.cgi?quicksearch=kgpg developers].<br />
<br />
=== Conflicts between gnome-keyring and gpg-agent ===<br />
<br />
{{Accuracy|See [[#GPG_AGENT_INFO]]}}<br />
<br />
While the Gnome keyring implements a GPG agent component, as of GnuPG version 2.1, GnuPG ignores the {{ic|GPG_AGENT_INFO}} environment variable, so that Gnome keyring can no longer be used as a GPG agent.<br />
<br />
=== mutt and gpg ===<br />
<br />
To be asked for your GnuPG password only once per session as of GnuPG 2.1, see [https://bbs.archlinux.org/viewtopic.php?pid=1490821#p1490821 this forum thread].<br />
<br />
=== "Lost" keys, upgrading to gnupg version 2.1 ===<br />
<br />
When {{ic|gpg --list-keys}} fails to show keys that used to be there, and applications complain about missing or invalid keys, some keys may not have been migrated to the new format.<br />
<br />
Please read [http://jo-ke.name/wp/?p=111 GnuPG invalid packet workaround]. Basically, it says that there is a bug with keys in the old {{ic|pubring.gpg}} and {{ic|secring.gpg}} files, which have now been superseded by the new {{ic|pubring.kbx}} file and the {{ic|private-keys-v1.d/}} subdirectory and files. Your missing keys can be recovered with the following commnads:<br />
<br />
$ cd<br />
$ cp -r .gnupg gnupgOLD<br />
$ gpg --export-ownertrust > otrust.txt<br />
$ gpg --import .gnupg/pubring.gpg<br />
$ gpg --import-ownertrust otrust.txt<br />
$ gpg --list-keys<br />
<br />
=== gpg hanged for all keyservers (when trying to receive keys) ===<br />
<br />
If gpg hanged with a certain keyserver when trying to receive keys, you might need to kill dirmngr in order to get access to other keyservers which are actually working, otherwise it might keeping hanging for all of them.<br />
<br />
=== Smartcard not detected ===<br />
<br />
Your user might not have the permission to access the smartcard which results in a {{ic|card error}} to be thrown, even though the card is correctly set up and inserted.<br />
<br />
One possible solution is to add a new group {{ic|scard}} including the users who need access to the smartcard.<br />
{{Accuracy|Is {{ic|MODE&#61;"664"}} necessary? Assigning a group, {{ic|MODE&#61;"660"}} may be enough?}}<br />
Then use an [[Udev#Writing_udev_rules|udev]] rule, similar to the following:<br />
{{hc|/etc/udev/rules.d/71-gnupg-ccid.rules|<nowiki><br />
ACTION=="add", SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="1050", ENV{ID_MODEL_ID}=="0116|0111", MODE="664", GROUP="scard"<br />
</nowiki>}}<br />
One needs to adapt VENDOR and MODEL according to the {{ic|lsusb}} output, the above example is for a YubikeyNEO.<br />
<br />
== See also ==<br />
<br />
* [http://gnupg.org/gph/en/manual.html The GNU Privacy Handbook]<br />
* [http://blog.sanctum.geek.nz/series/linux-crypto/ A more comprehensive gpg Tutorial]<br />
* [https://www.gnupg.org/faq/gnupg-faq.html GnuPG FAQ]<br />
* [https://help.riseup.net/en/security/message-security/openpgp/gpg-best-practices gpg.conf recommendations and best practices]<br />
* [https://github.com/ioerror/torbirdy/blob/master/gpg.conf Torbirdy gpg.conf]<br />
* [https://wiki.debian.org/Subkeys OpenPGP subkeys in Debian]</div>Chehrihttps://wiki.archlinux.org/index.php?title=Dm-crypt/Device_encryption&diff=409337Dm-crypt/Device encryption2015-11-16T02:32:42Z<p>Chehri: Warn about initramfs being world-readable by default.</p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:Encryption]]<br />
[[Category:File systems]]<br />
[[ja:Dm-crypt/デバイスの暗号化]]<br />
Back to [[Dm-crypt]].<br />
<br />
This section covers how to manually utilize ''dm-crypt'' from the command line to encrypt a system. <br />
<br />
== Preparation ==<br />
Before using {{pkg|cryptsetup}}, always make sure the {{ic|dm-crypt}} [[kernel module]] is loaded.<br />
<br />
== Cryptsetup usage ==<br />
''Cryptsetup'' is the command line tool to interface with ''dm-crypt'' for creating, accessing and managing encrypted devices. The tool was later expanded to support different encryption types that rely on the Linux kernel '''d'''evice-'''m'''apper and the '''crypt'''ographic modules. The most notable expansion was for the Linux Unified Key Setup (LUKS) extension, which stores all of the needed setup information for dm-crypt on the disk itself and abstracts partition and key management in an attempt to improve ease of use. Devices accessed via the device-mapper are called blockdevices. For further information see [[Disk encryption#Block device encryption]]. <br />
<br />
The tool is used as follows: <br />
<br />
# cryptsetup <OPTIONS> <action> <action-specific-options> <device> <dmname><br />
<br />
It has compiled-in defaults for the options and the encryption mode, which will be used if no others are specified on the command line. Have a look at <br />
<br />
$ cryptsetup --help <br />
<br />
which lists options, actions and the default parameters for the encryption modes in that order. A full list of options can be found on the man page.<br />
Since different parameters are required or optional, depending on encryption mode and action, the following sections point out differences further. Blockdevice encryption is fast, but speed matters a lot too. Since changing an encryption cipher of a blockdevice after setup is difficult, it is important to check ''dm-crypt'' performance for the individual parameters in advance: <br />
<br />
$ cryptsetup benchmark <br />
<br />
can give guidance on deciding for an algorithm and key-size prior to installation. If certain AES ciphers excel with a considerable higher throughput, these are probably the ones with hardware support in the CPU.<br />
<br />
{{Tip|You may want to practise encrypting a virtual hard drive in a [[:Category:Virtualization|virtual machine]] when learning.}}<br />
<br />
=== Cryptsetup passphrases and keys ===<br />
An encrypted blockdevice is protected by a key. A key is either: <br />
<br />
* a passphrase: see [[Disk encryption#Choosing a strong passphrase]].<br />
* a keyfile, see [[#Keyfiles]].<br />
<br />
Both key types have default maximum sizes: passphrases can be up to 512 characters and keyfiles up to 8192kB. <br />
<br />
An important distinction of ''LUKS'' to note at this point is that the key is used to unlock the master-key of a LUKS-encrypted device and can be changed with root access. Other encryption modes do not support changing the key after setup, because they do not employ a master-key for the encryption. See [[Disk encryption#Block device encryption]] for details.<br />
<br />
== Encryption options with dm-crypt ==<br />
''Cryptsetup'' supports different encryption operating modes to use with ''dm-crypt''. The most common (and default) is <br />
*{{ic|--type LUKS}} <br />
The other ones are <br />
*{{ic|--type plain}} for using dm-crypt plain mode, <br />
*{{ic|--type loopaes}} for a loopaes legacy mode, and <br />
*{{ic|--type tcrypt}} for a [[Truecrypt]] compatibility mode. <br />
<br />
The basic cryptographic options for encryption cipher and hashes available can be used for all modes and rely on the kernel cryptographic backend features. All that are loaded at runtime can be viewed with <br />
$ less /proc/crypto <br />
and are available to use as options. If the list is short, execute {{ic|cryptsetup benchmark}} which will trigger loading available modules. <br />
<br />
The following introduces encryption options for the first two modes. Note that the tables list options used in the respective examples in this article and not all available ones. <br />
<br />
=== Encryption options for LUKS mode ===<br />
The ''cryptsetup'' action to set up a new dm-crypt device in LUKS encryption mode is ''luksFormat''. Unlike the name implies, it does not format the device, but sets up the LUKS device header and encrypts the master-key with the desired cryptographic options. <br />
<br />
As LUKS is the default encryption mode:<br />
# cryptsetup -v luksFormat <device><br />
is all needed to perform it with default parameters ({{ic|-v}} optional). For comparison, we can specify the default options manually too: <br />
# cryptsetup -v --cipher aes-xts-plain64 --key-size 256 --hash sha1 --iter-time 1000 --use-urandom --verify-passphrase luksFormat <device> <br />
<br />
These options used are compared below in the left column, with another set in the right column: <br />
<br />
{| class="wikitable"<br />
! scope="col" style="text-align:left" | Options<br />
! scope="col" style="text-align:left" | Cryptsetup (1.6.2) defaults <br />
! scope="col" style="text-align:left" | Example<br />
! scope="col" style="text-align:left" | Comment<br />
|-<br />
! scope="row" style="text-align:right" | --cipher, -c<br />
| {{ic|aes-xts-plain64}}<br />
| {{ic|aes-xts-plain64}}<br />
| The example uses the same cipher as the default: the AES-[[Disk encryption#Ciphers_and_modes_of_operation|cipher]] with [[wikipedia:Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29|XTS]].<br />
|-<br />
! scope="row" style="text-align:right" | --key-size, -s<br />
| {{ic|256}}<br />
| {{ic|512}}<br />
| By default a 256 bit key-size is used. Note however that [[wikipedia:Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29|XTS splits the supplied key in half]]. So to use AES-256 instead of AES-128 you would have to set the XTS key-size to {{ic|512}}.<br />
|-<br />
! scope="row" style="text-align:right" | --hash, -h<br />
| {{ic|sha1}}<br />
| {{ic|sha512}}<br />
| Hash algorithm used for [[Disk encryption#Keys, keyfiles and passphrases|PBKDF2]]. Due to this processing, SHA1 is considered [http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/7093 adequate] as of January 2014. <br />
|-<br />
! scope="row" style="text-align:right" | --iter-time, -i<br />
| {{ic|1000}}<br />
| {{ic|5000}}<br />
| Number of milliseconds to spend with PBKDF2 passphrase processing. Using a hash stronger than sha1 results in less iterations if iter-time is not increased. <br />
|-<br />
! scope="row" style="text-align:right" | --use-random<br />
| {{ic|--use-'''u'''random}}<br />
| {{ic|--use-random}}<br />
| [[Random number generation|/dev/urandom]] is used as randomness source for the (long-term) volume master key. Avoid generating an insecure master key if low on entropy. The last three options only affect the encryption of the master key and not the disk operations. <br />
|-<br />
! scope="row" style="text-align:right" | --verify-passphrase, -y<br />
| Yes<br />
| -<br />
| Default only for luksFormat and luksAddKey. No need to type for Arch Linux with LUKS mode at the moment. <br />
|}<br />
<br />
The options used in the example column result in the following: <br />
# cryptsetup -v --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random luksFormat <device><br />
<br />
Please note that with release 1.6.0, the defaults have changed to an AES cipher in ''XTS'' mode. It is advised against using the previous default {{ic|--cipher aes-cbc-essiv}}, because of its known [https://en.wikipedia.org/wiki/Disk_encryption_theory#Cipher-block_chaining_.28CBC.29 issues] and practical [http://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/ attacks] against them.<br />
<br />
=== Encryption options for plain mode ===<br />
In dm-crypt ''plain'' mode, there is no master-key on the device, hence, there is no need to set it up. Instead the encryption options to be employed are used directly to create the mapping between an encrypted disk and a named device. The mapping can be created against a partition or a full device. In the latter case not even a partition table is needed. <br />
<br />
To create a ''plain'' mode mapping with cryptsetup's default parameters: <br />
# cryptsetup <options> open --type plain <device> <dmname><br />
Executing it will prompt for a password, which should have very high entropy. <br />
Below a comparison of default parameters with the example in [[Dm-crypt/Encrypting an entire system#Plain dm-crypt]]<br />
<br />
{| class="wikitable"<br />
! Option !! Cryptsetup defaults (1.6.2) !! Example !! Comment !! <br />
|-<br />
| '''--hash''' || {{ic|ripemd160}} || - || The hash is used to create the key from the passphrase; it is not used on a keyfile. <br />
|-<br />
| '''--cipher'''|| {{ic|aes-cbc-essiv:sha256}}|| {{ic|twofish-xts-plain64}} || The cipher consists of three parts: cipher-chainmode-IV generator. Please see [[Disk encryption#Ciphers and modes of operation]] for an explanation of these settings, and the [https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt DMCrypt documentation] for some of the options available. <br />
|-<br />
| '''--key-size'''||{{ic|256}}||{{ic|512}}||The key size (in bits). The size will depend on the cipher being used and also the chainmode in use. Xts mode requires twice the key size of cbc. <br />
|-<br />
| '''--offset'''||{{ic|0}}||{{ic|0}}||The offset from the beginning of the target disk from which to start the mapping<br />
|-<br />
| '''--key-file'''||default uses a passphrase||{{ic|/dev/sd''Z''}} (or e.g. /boot/keyfile.enc)||The device or file to be used as a key. See [[#Keyfiles]] for further details.<br />
|-<br />
| '''--keyfile-offset'''||{{ic|0}}||{{ic|0}}||Offset from the beginning of the file where the key starts (in bytes). This option is supported from ''cryptsetup'' 1.6.7 onwards. <br />
|-<br />
| '''--keyfile-size'''||{{ic|8192kB}}||- (default applies)||Limits the bytes read from the key file. This option is supported from ''cryptsetup'' 1.6.7 onwards. <br />
|}<br />
<br />
Using the device {{ic|/dev/sd''X''}}, the above right column example results in:<br />
{{bc|<nowiki># cryptsetup --cipher=twofish-xts-plain64 --offset=0 --key-file=</nowiki>/dev/sd''Z'' <nowiki>--key-size=512 open --type=plain /dev/sdX enc</nowiki>}}<br />
Unlike encrypting with LUKS, the above command must be executed ''in full'' whenever the mapping needs to be re-established, so it is important to remember the cipher, hash and key file details.<br />
We can now check that the mapping has been made:<br />
# fdisk -l<br />
An entry should now exist for {{ic|/dev/mapper/enc}}.<br />
<br />
== Encrypting devices with cryptsetup ==<br />
This section shows how to employ the options for creating new encrypted blockdevices and accessing them manually. <br />
<br />
=== Encrypting devices with LUKS mode ===<br />
==== Formatting LUKS partitions ====<br />
<br />
In order to setup a partition as an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup -c <cipher> -y -s <key size> luksFormat /dev/<partition name>|<br />
Enter passphrase: <password><br />
Verify passphrase: <password>}}<br />
first to setup the encrypted master-key. Checking results can be done with:<br />
# cryptsetup luksDump /dev/<drive><br />
<br />
This should be repeated for all partitions to be encrypted (except for {{ic|/boot}}). You will note that the dump not only shows the cipher header information, but also the key-slots in use for the LUKS partition. <br />
<br />
The following example will create an encrypted root partition using the default AES cipher in XTS mode with an effective 256-bit encryption <br />
{{bc|# cryptsetup -s 512 luksFormat /dev/sdaX}}<br />
<br />
=====Using LUKS to Format Partitions with a Keyfile=====<br />
<br />
When creating a new LUKS encrypted partition, a keyfile may be associated with the partition on its creation using:<br />
<br />
# cryptsetup -c <desired cipher> -s <key size> luksFormat /dev/<volume to encrypt> '''/path/to/mykeyfile'''<br />
<br />
This is accomplished by appending the bold area to the standard cryptsetup command which defines where the keyfile is located.<br />
<br />
See [[#Keyfiles]] for instructions on how to generate and manage keyfiles.<br />
<br />
====Unlocking/Mapping LUKS partitions with the device mapper ====<br />
<br />
Once the LUKS partitions have been created it is time to unlock them.<br />
<br />
The unlocking process will map the partitions to a new device name using the device mapper. This alerts the kernel that {{ic|/dev/<partition name>}} is actually an encrypted device and should be addressed through LUKS using the {{ic|/dev/mapper/<name>}} so as not to overwrite the encrypted data. To guard against accidental overwriting, read about the possibilities to [[Dm-crypt/Device encryption#Backup_and_restore|backup the cryptheader]] after finishing setup.<br />
<br />
In order to open an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup open --type luks /dev/<partition name> <device-mapper name>|<br />
Enter any LUKS passphrase: <password><br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
Usually the device mapped name is descriptive of the function of the partition that is mapped, example:<br />
<br />
# cryptsetup open --type luks /dev/sdaX root <br />
Once opened, the root partition device address would be {{ic|/dev/mapper/root}} instead of the partition (e.g. {{ic|/dev/sdaX}}). <br />
<br />
# cryptsetup open --type luks /dev/sda3 lvmpool <br />
For setting up LVM ontop the encryption layer the device file for the decrypted volume group would be anything like {{ic|/dev/mapper/lvmpool}} instead of {{ic|/dev/sdaX}}. LVM will then give additional names to all logical volumes created, e.g. {{ic|/dev/mapper/lvmpool-root}} and {{ic|/dev/mapper/lvmpool-swap}}.<br />
<br />
In order to write encrypted data into the partition it must be accessed through the device mapped name. The first step of access will typically be to create a filesystem <br />
# mkfs -t ext4 /dev/mapper/root<br />
and mount it <br />
# mount -t ext4 /dev/mapper/root /mnt<br />
The mounted blockdevice can then be used like any other partition. Once done, closing the device locks it again <br />
# umount /mnt<br />
# cryptsetup close root<br />
<br />
=== Encrypting devices with plain mode ===<br />
<br />
The creation and subsequent access of a ''dm-crypt'' plain mode encryption both require not more than using the ''cryptsetup'' {{ic|open}} action with correct [[Dm-crypt/Device encryption#Encryption_options_for_plain_mode|parameters]]. The following shows that with two examples of non-root devices, but adds a quirk by stacking both (i.e. the second is created inside the first). Obviously, stacking the encryption doubles overhead. The usecase here is simply to illustrate another example of the cipher option usage. <br />
<br />
A first mapper is created with ''cryptsetup's'' plain-mode defaults, as described in the table's left column above <br />
# cryptsetup --type plain -v open /dev/sdaX plain1 <br />
Enter passphrase: <br />
Command successful.<br />
# <br />
Now we add the second blockdevice inside it, using different encryption parameters and with an (optional) offset, create a filesystem and mount it <br />
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/mapper/plain1 plain2<br />
Enter passphrase: <br />
# lsblk -p <br />
NAME <br />
/dev/sda <br />
├─/dev/sdaX <br />
│ └─/dev/mapper/plain1 <br />
│ └─/dev/mapper/plain2 <br />
...<br />
# mkfs -t ext2 /dev/mapper/plain2<br />
# mount -t ext2 /dev/mapper/plain2 /mnt<br />
# echo "This is stacked. one passphrase per foot to shoot." > /mnt/stacked.txt<br />
We close the stack to check access works<br />
# cryptsetup close plain2<br />
# cryptsetup close plain1<br />
First, let's try to open the filesystem directly: <br />
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/sdaX plain2<br />
# mount -t ext2 /dev/mapper/plain2 /mnt<br />
mount: wrong fs type, bad option, bad superblock on /dev/mapper/plain2,<br />
missing codepage or helper program, or other error<br />
Why that did not work? Because the "plain2" starting block (10) is still encrypted with the cipher from "plain1". It can only be accessed via the stacked mapper. The error is arbitrary though, trying a wrong passphrase or wrong options will yield the same. For ''dm-crypt'' plain mode, the {{ic|open}} action will not error out itself. <br />
<br />
Trying again in correct order: <br />
# cryptsetup close plain2 # dysfunctional mapper from previous try<br />
# cryptsetup --type plain open /dev/sdaX plain1<br />
Enter passphrase: <br />
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/mapper/plain1 plain2 <br />
Enter passphrase: <br />
# mount /dev/mapper/plain2 /mnt && cat /mnt/stacked.txt<br />
This is stacked. one passphrase per foot to shoot.<br />
# exit<br />
''dm-crypt'' will handle stacked encryption with some mixed modes too. For example LUKS mode could be stacked on the "plain1" mapper. Its header would then be encrypted inside "plain1" when that is closed.<br />
<br />
Available for plain mode only is the option {{ic|--shared}}. With it a single device can be segmented into different non-overlapping mappers. We do that in the next example, using a ''loopaes'' compatible cipher mode for "plain2" this time: <br />
# cryptsetup --type plain --offset 0 --size 1000 open /dev/sdaX plain1 <br />
Enter passphrase: <br />
# cryptsetup --type plain --offset 1000 --size 1000 --shared --cipher=aes-cbc-lmk --hash=sha256 open /dev/sdaX plain2<br />
Enter passphrase: <br />
# lsblk -p<br />
NAME <br />
dev/sdaX <br />
├─/dev/sdaX <br />
│ ├─/dev/mapper/plain1 <br />
│ └─/dev/mapper/plain2 <br />
...<br />
As the devicetree shows both reside on the same level, i.e. are not stacked and "plain2" can be opened individually.<br />
<br />
== Cryptsetup actions specific for LUKS ==<br />
=== Key management ===<br />
It is possible to define up to 8 different keys per LUKS partition. This enables the user to create access keys for save backup storage: In a so-called key escrow, one key is used for daily usage, another kept in escrow to gain access to the partition in case the daily passphrase is forgotten or a keyfile is lost/damaged. Also a different key-slot could be used to grant access to a partition to a user by issuing a second key and later revoking it again. <br />
<br />
Once an encrypted partition has been created, the initial keyslot 0 is created (if no other was specified manually). Additional keyslots are numbered from 1 to 7. Which keyslots are used can be seen by issuing <br />
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki>grep BLED|<br />
Key Slot 0: ENABLED<br />
Key Slot 1: ENABLED<br />
Key Slot 2: ENABLED<br />
Key Slot 3: DISABLED<br />
Key Slot 4: DISABLED<br />
Key Slot 5: DISABLED<br />
Key Slot 6: DISABLED<br />
Key Slot 7: DISABLED}}<br />
<br />
Where <device> is the volume containing the LUKS header. This and all the following commands in this section work on header backup files as well. <br />
<br />
==== Adding LUKS keys ====<br />
<br />
Adding new keyslots is accomplished using cryptsetup with the {{ic|luksAddKey}} action. For safety it will always, i.e. also for already unlocked devices, ask for a valid existing key ("any passphrase") before a new one may be entered:<br />
<br />
# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) <br />
Enter any passphrase:<br />
Enter new passphrase for key slot:<br />
Verify passphrase: <br />
<br />
If {{ic|/path/to/<additionalkeyfile>}} is given, cryptsetup will add a new keyslot for <additionalkeyfile>. Otherwise a new passphrase will be prompted for twice. For using an existing ''keyfile'' to authorize the action, the {{ic|--key-file}} or {{ic|-d}} option followed by the "old" <keyfile> will try to unlock all available keyfile keyslots:<br />
<br />
# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) -d /path/to/<keyfile><br />
<br />
If it is intended to use multiple keys and change or revoke them, the {{ic|--key-slot}} or {{ic|-S}} option may be used to specify the slot: <br />
# cryptsetup luksAddKey /dev/<device> -S 6 <br />
Enter any passphrase: <br />
Enter new passphrase for key slot: <br />
Verify passphrase:<br />
# cryptsetup luksDump /dev/sda8 |grep 'Slot 6'<br />
Key Slot 6: ENABLED<br />
<br />
To show an associated action in this example, we decide to change the key right away: <br />
# cryptsetup luksChangeKey /dev/<device> -S 6 <br />
Enter LUKS passphrase to be changed: <br />
Enter new LUKS passphrase: <br />
<br />
before continuing to remove it.<br />
<br />
==== Removing LUKS keys ====<br />
<br />
There are three different actions to remove keys from the header: <br />
*{{ic|luksRemoveKey}} is used to remove a key by specifying its passphrase/key-file. <br />
*{{ic|luksKillSlot}} may be used to remove a key from a specific key slot (using another key). Obviously, this is extremely useful if you have forgotten a passphrase, lost a key-file, or have no access to it. <br />
*{{ic|luksErase}} is used to quickly remove '''all''' active keys. <br />
{{warning|<br />
*All above actions can be used to irrevocably delete the last active key for an encrypted device! <br />
*The {{ic|luksErase}} command was added in version 1.6.4 to quickly nuke access to the device. This action '''will not''' prompt for a valid passphrase! It will not [[Dm-crypt/Drive_preparation#Wipe_LUKS_header|wipe the LUKS header]], but all keyslots at once and you will, therefore, not be able to regain access unless you have a valid backup of the LUKS header.}} <br />
<br />
For above warning it is good to know the key we want to '''keep''' is valid. An easy check is to unlock the device with the {{ic|-v}} option, which will specify which slot it occupies: <br />
{{bc|# cryptsetup -v open /dev/<device> testcrypt<br />
Enter passphrase for /dev/<device>: <br />
Key slot 1 unlocked.<br />
Command successful.}}<br />
<br />
Now we can remove the key added in the previous subsection using its passphrase: <br />
# cryptsetup luksRemoveKey /dev/<device><br />
Enter LUKS passphrase to be deleted: <br />
If we had used the same passphrase for two keyslots, the first slot would be wiped now. Only executing it again would remove the second one. <br />
<br />
Alternatively, we can specify the key slot: <br />
# cryptsetup luksKillSlot /dev/<device> 6<br />
Enter any remaining LUKS passphrase:<br />
<br />
Note that in both cases, no confirmation was required.<br />
# cryptsetup luksDump /dev/sda8 |grep 'Slot 6'<br />
Key Slot 6: DISABLED<br />
To re-iterate the warning above: If the same passphrase had been used for key slots 1 and 6, both would be gone now.<br />
<br />
=== Backup and restore ===<br />
If the header of a LUKS encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much as a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. A damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table.<br />
<br />
Therefore, having a backup of the header and storing it on another disk might be a good idea.<br />
<br />
'''Attention:''' Many people recommend NOT backing up the cryptheader, but even so it's a single point of failure!<br />
In short, the problem is that LUKS is not aware of the duplicated cryptheader, which contains the master key used to encrypt all files on the partition. Of course this master key is encrypted with your passphrases or keyfiles.<br />
But if one of those gets compromised and you want to revoke it you have to do this on all copies of the cryptheader!<br />
I.e. if someone obtains a copy of the cryptheader and one of your keys he can decrypt the master key and access all your data.<br />
Of course the same is true for all backups you create of partitions. So you decide if you are one of those paranoids brave enough to go without a backup for the sake of security or not. See also the [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#6-backup-and-data-recovery LUKS FAQ] for further details on this.<br />
<br />
==== Backup using cryptsetup ====<br />
Cryptsetup's {{ic|luksHeaderBackup}} action stores a binary backup of the LUKS header and keyslot area:<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /mnt/<backup>/<file>.img<br />
where <device> is the partition containing the LUKS volume.<br />
<br />
{{Tip|You can also back up the plaintext header into ramfs and encrypt it in example with gpg before writing to persistent backup storage by executing the following commands.}}<br />
{{bc|# mkdir /root/<tmp>/<br />
# mount ramfs /root/<tmp>/ -t ramfs<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /root/<tmp>/<file>.img<br />
# gpg2 --recipient <User ID> --encrypt /root/<tmp>/<file>.img <br />
# cp /root/<tmp>/<file>.img.gpg /mnt/<backup>/<br />
# umount /root/<tmp>}}<br />
{{Warning|Tmpfs can swap to harddisk if low on memory so it is not recommended here.}}<br />
<br />
==== Restore using cryptsetup ====<br />
<br />
{{Warning|Restoring the wrong header or restoring to an unencrypted partition will cause data loss! The action can not perform a check whether the header is actually the ''correct'' one for that particular device.}} <br />
<br />
In order to evade restoring a wrong header, you can ensure it does work by using it as a remote {{ic|--header}} first: <br />
<br />
# cryptsetup -v --header /mnt/<backup>/<file>.img open /dev/<device> test <br />
Key slot 0 unlocked.<br />
Command successful.<br />
# mount /dev/mapper/test /mnt/test && ls /mnt/test <br />
# umount /mnt/test <br />
# cryptsetup close test <br />
<br />
Now that the check succeeded, the restore may be performed: <br />
# cryptsetup luksHeaderRestore /dev/<device> --header-backup-file ./mnt/<backup>/<file>.img<br />
<br />
Now that all the keyslot areas are overwritten; only active keyslots from the backup file are available after issuing the command.<br />
<br />
==== Manual backup and restore ====<br />
The header always resides at the beginning of the device and a backup can be performed without access to ''cryptsetup'' as well. First you have to find out the payload offset of the crypted partition:<br />
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki> grep "Payload offset"|<br />
Payload offset: 4040}}<br />
Second check the sector size of the drive<br />
{{hc|# fdisk -l /dev/<device> <nowiki>|</nowiki>grep "Sector size"|Sector size (logical/physical): 512 bytes / 512 bytes}}<br />
<br />
Now that you know the values, you can backup the header with a simple dd command:<br />
# dd if=/dev/<device> of=/path/to/<file>.img bs=512 count=4040<br />
and store it safely.<br />
<br />
A restore can then be performed using the same values as when backing up:<br />
# dd if=./<file>.img of=/dev/<device> bs=512 count=4040<br />
<br />
=== Re-encrypting devices ===<br />
<br />
{{Expansion|Introduce ''cryptsetup-reencrypt''.|Talk:Dm-crypt/Specialties#Recommend TRIM on non-FDE SSDs.3F}}<br />
<br />
The {{Pkg|cryptsetup}} package features the ''cryptsetup-reencrypt'' tool. It can be used to convert an existing unencrypted filesystem to a LUKS encrypted one (option {{ic|--new}}) and permanently remove LUKS encryption ({{ic|--decrypt}}) from a device. As its name suggests it can also be used to re-encrypt an existing LUKS encrypted device. For re-encryption it is possible to change the [[#Encryption options for LUKS mode]]. ''cryptsetup-reencrypt'' actions can be performed to unmounted devices only. See {{ic|man cryptsetup-reencrypt}} for more information. <br />
<br />
One application of re-encryption may be to secure the data again after a passphrase or [[#Keyfiles|keyfile]] has been compromised ''and'' one cannot be certain that no copy of the LUKS header has been obtained. For example, if only a passphrase has been shoulder-surfed but no physical/logical access to the device happened, it would be enough to change the respective passphrase/key only ([[#Key management]]). <br />
<br />
{{Warning|The tool has been available and improved since 2012, but it is still marked '''experimental'''. Always make sure a '''reliable backup''' is available before using it!}}<br />
<br />
The following shows an example to encrypt an unencrypted filesystem partition and a re-encryption of an existing LUKS device. <br />
<br />
==== Encrypt an unencrypted filesystem ====<br />
<br />
A LUKS encryption header is always stored at the beginning of the device. Since an existing filesystem will usually be allocated all partition sectors, the first step is to shrink it to make space for the LUKS header. <br />
<br />
The [[#Encryption_options_for_LUKS_mode|default]] LUKS header encryption cipher requires {{ic|4096}} 512-byte sectors. We already checked space and keep it simple by shrinking the existing {{ic|ext4}} filesystem on {{ic|/dev/sdaX}} to its current possible minimum: <br />
<br />
{{bc|# umount /mnt<br />
# e2fsck -f /dev/sdaX <br />
e2fsck 1.43-WIP (18-May-2015)<br />
Pass 1: Checking inodes, blocks, and sizes<br />
...<br />
/dev/sda6: 12/166320 files (0.0% non-contiguous), 28783/665062 blocks<br />
# resize2fs -M /dev/sdaX<br />
resize2fs 1.43-WIP (18-May-2015)<br />
Resizing the filesystem on /dev/sdaX to 26347 (4k) blocks.<br />
The filesystem on /dev/sdaX is now 26347 (4k) blocks long.}}<br />
<br />
Now we encrypt it, using the default cipher we do not have to specify it explicitly. Note there is no option (yet) to double-check the passphrase before encryption starts, be careful not to mistype: <br />
<br />
{{hc|# cryptsetup-reencrypt /dev/sdaX --new --reduce-device-size 4096S|<br />
WARNING: this is experimental code, it can completely break your data.<br />
Enter new passphrase: <br />
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed 37,6 MiB/s}}<br />
<br />
After it finished, the encryption was performed to the full partition, i.e. not only the space the filesystem was shrunk to ({{ic|sdaX}} has {{ic|2.6GiB}} and the CPU used in the example has no hardware AES instructions). As a final step we extend the filesystem of the now encrypted device again to occupy available space: <br />
<br />
{{bc|# cryptsetup open /dev/sdaX recrypt <br />
Enter passphrase for /dev/sdaX: <br />
...<br />
# resize2fs /dev/mapper/recrypt <br />
resize2fs 1.43-WIP (18-May-2015)<br />
Resizing the filesystem on /dev/mapper/recrypt to 664807 (4k) blocks.<br />
The filesystem on /dev/mapper/recrypt is now 664807 (4k) blocks long.<br />
# mount /dev/mapper/recrypt /mnt}}<br />
<br />
and are done.<br />
<br />
==== Re-encrypting an existing LUKS partition ====<br />
<br />
In this example an existing LUKS device is re-encrypted. <br />
<br />
{{Warning|Double-check you specify encryption options for ''cryptsetup-reencrypt'' correctly and ''never'' re-encrypt without a '''reliable backup'''! As of September 2015 the tool '''does''' accept invalid options and damage the LUKS header, if not used correctly!}}<br />
<br />
In order to re-encrypt a device with its existing encryption options, they do not need to be specified. A simple: <br />
<br />
{{hc|# cryptsetup-reencrypt /dev/sdaX| <br />
WARNING: this is experimental code, it can completely break your data.<br />
Enter passphrase for key slot 0: <br />
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed 36,5 MiB/s}}<br />
<br />
performs it. <br />
<br />
A possible usecase is to re-encrypt LUKS devices which have non-current encryption options. Apart from above warning on specifying options correctly, the ability to change the LUKS header may also be limited by its size. For example, if the device was initially encrypted using a CBC mode cipher and 128 bit key-size, the LUKS header will be half the size of above mentioned {{ic|4096}} sectors: <br />
{{hc|# cryptsetup luksDump /dev/sdaX <nowiki>|</nowiki>grep -e "mode" -e "Payload" -e "MK bits"|<br />
Cipher mode: cbc-essiv:sha256<br />
Payload offset: '''2048'''<br />
MK bits: 128}}<br />
While it is possible to upgrade the encryption of such a device, it is currently only feasible in two steps. First, re-encrypting with the same encryption options, but using the {{ic|--reduce-device-size}} option to make further space for the larger LUKS header. Second, re-encypt the whole device again with the desired cipher. For this reason and the fact that a backup should be created in any case, creating a new, fresh encrypted device to restore into is always the faster option.<br />
<br />
== Keyfiles ==<br />
<br />
{{Note|This section describes using a plaintext keyfile. If you want to encrypt your keyfile giving you two factor authentication see [[Dm-crypt/Specialties#Using_GPG_or_OpenSSL_Encrypted_Keyfiles|Using GPG or OpenSSL Encrypted Keyfiles]] for details, but please still read this section.}}<br />
<br />
'''What is a keyfile?'''<br />
<br />
A keyfile is a file whose data is used as the passphrase to unlock an encrypted volume.<br />
That means if such a file is lost or changed, decrypting the volume may no longer be possible.<br />
<br />
{{Tip|Define a passphrase in addition to the keyfile for backup access to encrypted volumes in the event the defined keyfile is lost or changed.}}<br />
<br />
'''Why use a keyfile?'''<br />
<br />
There are many kinds of keyfiles. Each type of keyfile used has benefits and disadvantages summarized below:<br />
<br />
=== Types of keyfiles ===<br />
==== passphrase ====<br />
<br />
This is a keyfile containing a simple passphrase. The benefit of this type of keyfile is that if the file is lost the data it contained is known and hopefully easily remembered by the owner of the encrypted volume. However the disadvantage is that this does not add any security over entering a passphrase during the initial system start.<br />
<br />
Example: 1234<br />
<br />
==== randomtext ====<br />
<br />
This is a keyfile containing a block of random characters. The benefit of this type of keyfile is that it is much more resistant to dictionary attacks than a simple passphrase. An additional strength of keyfiles can be utilized in this situation which is the length of data used. Since this is not a string meant to be memorized by a person for entry, it is trivial to create files containing thousands of random characters as the key. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase.<br />
<br />
Example: fjqweifj830149-57 819y4my1-38t1934yt8-91m 34co3;t8y;9p3y-<br />
<br />
==== binary ====<br />
<br />
This is a binary file that has been defined as a keyfile. When identifying files as candidates for a keyfile, it is recommended to choose files that are relatively static such as photos, music, video clips. The benefit of these files is that they serve a dual function which can make them harder to identify as keyfiles. Instead of having a text file with a large amount of random text, the keyfile would look like a regular image file or music clip to the casual observer. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase. Additionally, there is a theoretical loss of randomness when compared to a randomly generated text file. This is due to the fact that images, videos and music have some intrinsic relationship between neighboring bits of data that does not exist for a text file. However this is controversial and has never been exploited publicly.<br />
<br />
Example: images, text, video, ...<br />
<br />
=== Creating a keyfile with random characters ===<br />
<br />
==== Storing the keyfile on a filesystem ====<br />
<br />
A keyfile can be of arbitrary content and size. <br />
<br />
Here {{ic|dd}} is used to generate a keyfile of 2048 random bytes, storing it in the file {{ic|/etc/mykeyfile}}:<br />
<br />
# dd bs=512 count=4 if=/dev/urandom of=/etc/mykeyfile iflag=fullblock<br />
<br />
If you are planning to store the keyfile on an external device, you can also simply change the outputfile to the corresponding directory:<br />
<br />
# dd bs=512 count=4 if=/dev/urandom of=/media/usbstick/mykeyfile iflag=fullblock<br />
<br />
===== Securely overwriting stored keyfiles =====<br />
<br />
If you stored your temporary keyfile on a physical storage device, and want to delete it, remember to not just remove the keyfile later on, but use something like<br />
<br />
# shred --remove --zero mykeyfile<br />
<br />
to securely overwrite it. For overaged filesystems like FAT or ext2 this will suffice while in the case of journaling filesystems, flash memory hardware and other cases it is highly recommended to [[Securely wipe disk|wipe the entire device]] or at least the keyfiles partition.<br />
<br />
==== Storing the keyfile in tmpfs ====<br />
<br />
Alternatively, you can mount a tmpfs for storing the keyfile temporarily:<br />
<br />
# mkdir mytmpfs<br />
# mount tmpfs mytmpfs -t tmpfs -o size=32m<br />
# cd mytmpfs<br />
<br />
The advantage is that it resides in RAM and not on a physical disk, therefore it can not be recovered after unmounting the tmpfs. On the other hand this requires you to copy the keyfile to another filesystem you consider secure before unmounting.<br />
<br />
=== Configuring LUKS to make use of the keyfile ===<br />
<br />
Add a keyslot for the keyfile to the LUKS header:<br />
<br />
{{hc|# cryptsetup luksAddKey /dev/sda2 mykeyfile|<br />
Enter any LUKS passphrase:<br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
=== Unlocking a secondary partition at boot ===<br />
<br />
If the keyfile for a secondary file system is itself stored inside an encrypted root, it is safe while the system is powered off but can be sourced to automatically unlock the mount during with boot via [[Dm-crypt/System configuration#crypttab|crypttab]]. Following above first example <br />
{{hc|/etc/crypttab|home /dev/sda2 /etc/mykeyfile}}<br />
is all needed for unlocking, and <br />
{{hc|/etc/fstab|/dev/mapper/home /home ext4 defaults 0 2}} for mounting the LUKS blockdevice with the generated keyfile.<br />
{{Tip|If you prefer to use a {{ic|--plain}} mode blockdevice, the encryption options necessary to unlock it are specified in {{ic|/etc/crypttab}}. Take care to apply the systemd workaround mentioned in [[Dm-crypt/System configuration#crypttab|crypttab]] in this case.}}<br />
<br />
=== Unlocking the root partition at boot ===<br />
<br />
This is simply a matter of configuring [[mkinitcpio]] to include the necessary modules or files and configuring the [[Dm-crypt/System_configuration#cryptkey|cryptkey]] [[Kernel_parameters|kernel parameter]] to know where to find the keyfile.<br />
<br />
Two cases will be covered:<br />
<br />
# Using a keyfile stored on an external media (here a USB stick)<br />
# Using a keyfile embedded in the initramfs <br />
<br />
==== With a keyfile stored on an external media ====<br />
<br />
===== Configuring mkinitcpio =====<br />
<br />
You have to add two extra modules in your {{ic|/etc/mkinitcpio.conf}}, one for the drive's file system ({{ic|vfat}} module in the example below) and one for the codepage ({{ic|nls_cp437}} module) :<br />
MODULES="nls_cp437 vfat"<br />
<br />
In this example it is assumed that you use a FAT formatted USB drive ({{ic|vfat}} module). Replace those module names if you use another file system on your USB stick (e.g. {{ic|ext2}}) or another codepage. Users running the stock Arch kernel should stick to the codepage mentioned here. If it complains of bad superblock and bad codepage at boot, then you need an extra codepage module to be loaded. For instance, you may need {{ic|nls_iso8859-1}} module for {{ic|iso8859-1}} codepage.<br />
<br />
If you have a non-US keyboard, it might prove useful to load your keyboard layout before you are prompted to enter the password to unlock the root partition at boot. For this, you will need the {{ic|keymap}} hook before {{ic|encrypt}}.<br />
<br />
Generate a new initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
===== Configuring the kernel parameters =====<br />
<br />
Add the following options to the [[kernel parameters]]:<br />
<br />
cryptdevice=/dev/''<partition1>'':root cryptkey=/dev/''<partition2>'':<fstype>:<path><br />
<br />
For example:<br />
<br />
cryptdevice=/dev/sda3:root cryptkey=/dev/sdb1:vfat:/keys/secretkey<br />
<br />
Choosing a plain filename for your key provides a bit of 'security through obscurity'. The keyfile can not be a hidden file, that means the filename must not start with a dot, or the {{ic|encrypt}} hook will fail to find the keyfile during the boot process.<br />
<br />
The naming of device nodes like {{ic|/dev/sdb1}} is not guaranteed to stay the same across reboots. It is more reliable to access the device with udev's [[persistent block device naming]] instead. To assure that the {{ic|encrypt}} hook finds your keyfile when reading it from an external storage device, persistent block device names must be used. See the article [[persistent block device naming]].<br />
<br />
==== With a keyfile embedded in the initramfs ====<br />
<br />
{{Warning|Use an embedded keyfile '''only''' if you have some form of authentication mechanism beforehand that protects the keyfile sufficiently. Otherwise auto-decryption will occur, defeating completely the purpose of block device encryption.}}<br />
<br />
This method allows to use a specially named keyfile that will be embedded in the [[initramfs]] and picked up by the {{ic|encrypt}} [[Mkinitcpio#HOOKS|hook]] to unlock the root filesystem automatically. It may be useful to apply when using the [[GRUB#Boot partition|GRUB early cryptodisk]] feature, in order to avoid entering two passphrases during boot.<br />
<br />
By default the {{ic|encrypt}} hook takes the file specified in the {{ic|cryptkey}} kernel parameter and use it to unlock {{ic|cryptdevice}}. However, the code defaults to use {{ic|/crypto_keyfile.bin}} if it exists.[https://projects.archlinux.org/svntogit/packages.git/tree/trunk/encrypt_hook?h=packages/cryptsetup#n8] If the initramfs contains a valid key with this name, decryption will occur automatically without the need to configure the {{ic|cryptkey}} parameter.<br />
<br />
[[#Creating_a_keyfile_with_random_characters|Generate the keyfile]], give it suitable permissions and [[#Adding_LUKS_keys|add it as a LUKS key]]:<br />
<br />
# dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin<br />
# chmod 000 /crypto_keyfile.bin<br />
# chmod 600 /boot/initramfs-linux*<br />
# cryptsetup luksAddKey /dev/sdX# /crypto_keyfile.bin<br />
<br />
{{Warning|When initramfs' permissions are set to 644 (by default), then all users will be able to dump the keyfile. Make sure the permissions are still 400 if you install a new kernel.}}<br />
<br />
Include the key in [[Mkinitcpio#BINARIES_and_FILES|mkinitcpio FILES array]]:<br />
<br />
{{hc|/etc/mkinitcpio.conf|2=FILES="/crypto_keyfile.bin"}}<br />
<br />
Finally [[Mkinitcpio#Image_creation_and_activation|Regenerate your initramfs]].<br />
<br />
On the next reboot you should only have to enter your container decryption passphrase once.<br />
<br />
([http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/#bonus-login-once source])</div>Chehrihttps://wiki.archlinux.org/index.php?title=ZFS&diff=406682ZFS2015-10-24T20:07:00Z<p>Chehri: Typo correction.</p>
<hr />
<div>[[Category:File systems]]<br />
[[ja:ZFS]]<br />
{{Related articles start}}<br />
{{Related|File systems}}<br />
{{Related|Experimenting with ZFS}}<br />
{{Related|Installing Arch Linux on ZFS}}<br />
{{Related|ZFS on FUSE}}<br />
{{Related articles end}}<br />
<br />
[[Wikipedia:ZFS|ZFS]] is an advanced filesystem created by [[Wikipedia:Sun Microsystems|Sun Microsystems]] (now owned by Oracle) and released for OpenSolaris in November 2005. Features of ZFS include: pooled storage (integrated volume management – zpool), [[Wikipedia:Copy-on-write|Copy-on-write]], [[Wikipedia:Snapshot (computer storage)|snapshots]], data integrity verification and automatic repair (scrubbing), [[Wikipedia:RAID-Z|RAID-Z]], a maximum [[Wikipedia:Exabyte|16 Exabyte]] file size, and a maximum [[Wikipedia:Zettabyte|256 Zettabyte]] volume size. ZFS is licensed under the [[Wikipedia:CDDL|Common Development and Distribution License]] (CDDL).<br />
<br />
Described as [http://web.archive.org/web/20060428092023/http://www.sun.com/2004-0914/feature/ "The last word in filesystems"] ZFS is stable, fast, secure, and future-proof. Being licensed under the CDDL, and thus incompatible with GPL, it is not possible for ZFS to be distributed along with the Linux Kernel. This requirement, however, does not prevent a native Linux kernel module from being developed and distributed by a third party, as is the case with [http://zfsonlinux.org/ zfsonlinux.org] (ZOL).<br />
<br />
ZOL is a project funded by the [https://www.llnl.gov/ Lawrence Livermore National Laboratory] to develop a native Linux kernel module for its massive storage requirements and super computers.<br />
<br />
==Installation==<br />
=== General ===<br />
Install {{AUR|zfs-git}} from the [[Arch User Repository]] or the [[Unofficial user repositories#demz-repo-core|demz-repo-core]] repository. This package has {{AUR|zfs-utils-git}} and {{AUR|spl-git}} as a dependency, which in turn has {{AUR|spl-utils-git}} as dependency. SPL (Solaris Porting Layer) is a Linux Kernel module implementing Solaris APIs for ZFS compatibility.<br />
<br />
{{Note|1=The zfs-git package replaces the original zfs package from [[AUR]]. ZFSonLinux.org is slow to make stable releases and kernel API changes broke stable builds of ZFSonLinux for Arch. Changes submitted to the master branch of the ZFSonLinux repository are regression tested and therefore considered stable.}}<br />
<br />
For users that desire ZFS builds from stable releases, {{AUR|zfs-lts}} is available from the [[Arch User Repository]] or the [[Unofficial user repositories#demz-repo-core|demz-repo-core]] repository. A script to build ZFS and its dependencies automatically can be found [[#Automated build script|here]].<br />
<br />
{{warning|The ZFS and SPL kernel modules are tied to a specific kernel version. It would not be possible to apply any kernel updates until updated packages are uploaded to AUR or the [[Unofficial user repositories#demz-repo-core|demz-repo-core]] repository.}}<br />
<br />
Test the installation by issuing {{ic|zpool status}} on the command line. If an "insmod" error is produced, try {{ic|depmod -a}}.<br />
<br />
=== Root on ZFS ===<br />
<br />
When performing an Arch install on ZFS, {{AUR|zfs-git}} and its dependencies can be installed in the archiso environment as outlined in the previous section.<br />
<br />
It may be useful to prepare a [[#Embed the archzfs packages into an archiso|customized archiso]] with ZFS support builtin. For a much more detailed guide on installing Arch with ZFS as its root file system, see [[Installing Arch Linux on ZFS]].<br />
<br />
==Experimenting with ZFS ==<br />
<br />
Users wishing to experiment with ZFS on ''virtual block devices'' (known in ZFS terms as VDEVs) which can be simple files like {{ic|~/zfs0.img}} {{ic|~/zfs1.img}} {{ic|~/zfs2.img}} etc. with no possibility of real data loss are encouraged to see the [[Experimenting with ZFS]] article. Common tasks like building a RAIDZ array, purposefully corrupting data and recovering it, snapshotting datasets, etc. are covered.<br />
<br />
==Configuration==<br />
<br />
ZFS is considered a "zero administration" filesystem by its creators; therefore, configuring ZFS is very straight forward. Configuration is done primarily with two commands: {{ic|zfs}} and {{ic|zpool}}.<br />
<br />
===Automatic Start===<br />
<br />
For ZFS to live by its "zero administration" namesake, the zfs daemon must be loaded at startup. A benefit to this is that it is not necessary to mount the zpool in {{ic|/etc/fstab}}; the zfs daemon can import and mount zfs pools automatically. The daemon mounts the zfs pools reading the file {{ic|/etc/zfs/zpool.cache}}.<br />
<br />
For each pool you want automatically mounted by the zfs daemon execute:<br />
# zpool set cachefile=/etc/zfs/zpool.cache <pool><br />
<br />
Enable the service so it is automatically started at boot time:<br />
<br />
# systemctl enable zfs.target<br />
<br />
To manually start the daemon:<br />
<br />
# systemctl start zfs.target<br />
<br />
==Create a storage pool==<br />
<br />
Use {{ic| # parted --list}} to see a list of all available drives. It is not necessary nor recommended to partition the drives before creating the zfs filesystem.<br />
<br />
{{Note|If some or all device have been used in a software RAID set it is paramount to erase any old RAID configuration information. ([[Mdadm#Prepare_the_Devices]]) }}<br />
<br />
{{Warning|For Advanced Format Disks with 4KB sector size, an ashift of 12 is recommended for best performance. Advanced Format disks emulate a sector size of 512 bytes for compatibility with legacy systems, this causes ZFS to sometimes use an ashift option number that is not ideal. Once the pool has been created, the only way to change the ashift option is to recreate the pool. Using an ashift of 12 would also decrease available capacity. See [http://zfsonlinux.org/faq.html#PerformanceConsideration 1.10 What’s going on with performance?], [http://zfsonlinux.org/faq.html#HowDoesZFSonLinuxHandleAdvacedFormatDrives 1.15 How does ZFS on Linux handle Advanced Format disks?], and [http://wiki.illumos.org/display/illumos/ZFS+and+Advanced+Format+disks ZFS and Advanced Format disks].}}<br />
<br />
Having identified the list of drives, it is now time to get the id's of the drives to add to the zpool. The [http://zfsonlinux.org/faq.html#WhatDevNamesShouldIUseWhenCreatingMyPool zfs on Linux developers recommend] using device ids when creating ZFS storage pools of less than 10 devices. To find the id's, simply:<br />
<br />
# ls -lh /dev/disk/by-id/<br />
<br />
The ids should look similar to the following:<br />
<br />
lrwxrwxrwx 1 root root 9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0JKRR -> ../../sdc<br />
lrwxrwxrwx 1 root root 9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0JTM1 -> ../../sde<br />
lrwxrwxrwx 1 root root 9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0KBP8 -> ../../sdd<br />
lrwxrwxrwx 1 root root 9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0KDGY -> ../../sdb<br />
<br />
{{Style|Missing references to [[Persistent block device naming]], it is useless to explain the differences (or even what they are) here.}}<br />
<br />
Disk labels and UUID can also be used for ZFS mounts by using [[GUID Partition Table|GPT]] partitions. ZFS drives have labels but Linux is unable to read them at boot. Unlike [[Master Boot Record|MBR]] partitions, GPT partitions directly support both UUID and labels independent of the format inside the partition. Partitioning rather than using the whole disk for ZFS offers two additional advantages. The OS does not generate bogus partition numbers from whatever unpredictable data ZFS has written to the partition sector, and if desired, you can easily over provision SSD drives, and slightly over provision spindle drives to ensure that different models with slightly different sector counts can zpool replace into your mirrors. This is a lot of organization and control over ZFS using readily available tools and techniques at almost zero cost.<br />
<br />
Use [[GUID Partition Table|gdisk]] to partition the all or part of the drive as a single partition. gdisk does not automatically name partitions so if partition labels are desired use gdisk command "c" to label the partitions. Some reasons you might prefer labels over UUID are: labels are easy to control, labels can be titled to make the purpose of each disk in your arrangement readily apparent, and labels are shorter and easier to type. These are all advantages when the server is down and the heat is on. GPT partition labels have plenty of space and can store most international characters [[wikipedia:GUID_Partition_Table#Partition_entries]] allowing large data pools to be labeled in an organized fashion.<br />
<br />
Drives partitioned with GPT have labels and UUID that look like this. <br />
<br />
# ls -l /dev/disk/by-partlabel<br />
# lrwxrwxrwx 1 root root 10 Apr 30 01:44 zfsdata1 -> ../../sdd1<br />
# lrwxrwxrwx 1 root root 10 Apr 30 01:44 zfsdata2 -> ../../sdc1<br />
# lrwxrwxrwx 1 root root 10 Apr 30 01:59 zfsl2arc -> ../../sda1<br />
<br />
# ls -l /dev/disk/by-partuuid<br />
# lrwxrwxrwx 1 root root 10 Apr 30 01:44 148c462c-7819-431a-9aba-5bf42bb5a34e -> ../../sdd1<br />
# lrwxrwxrwx 1 root root 10 Apr 30 01:59 4f95da30-b2fb-412b-9090-fc349993df56 -> ../../sda1<br />
# lrwxrwxrwx 1 root root 10 Apr 30 01:44 e5ccef58-5adf-4094-81a7-3bac846a885f -> ../../sdc1<br />
<br />
Now, finally, create the ZFS pool:<br />
<br />
# zpool create -f -m <mount> <pool> raidz <ids><br />
<br />
* '''create''': subcommand to create the pool.<br />
<br />
* '''-f''': Force creating the pool. This is to overcome the "EFI label error". See [[#Does not contain an EFI label]].<br />
<br />
* '''-m''': The mount point of the pool. If this is not specified, then the pool will be mounted to {{ic|/<pool>}}.<br />
<br />
* '''pool''': This is the name of the pool.<br />
<br />
* '''raidz''': This is the type of virtual device that will be created from the pool of devices. Raidz is a special implementation of raid5. See [https://blogs.oracle.com/bonwick/entry/raid_z Jeff Bonwick's Blog -- RAID-Z] for more information about raidz.<br />
<br />
* '''ids''': The names of the drives or partitions that to include into the pool. Get it from {{ic|/dev/disk/by-id}}.<br />
<br />
Here is an example for the full command:<br />
<br />
# zpool create -f -m /mnt/data bigdata \<br />
raidz \<br />
ata-ST3000DM001-9YN166_S1F0KDGY \<br />
ata-ST3000DM001-9YN166_S1F0JKRR \<br />
ata-ST3000DM001-9YN166_S1F0KBP8 \<br />
ata-ST3000DM001-9YN166_S1F0JTM1<br />
<br />
=== Advanced format disks ===<br />
<br />
In case Advanced Format disks are used which have a native sector size of 4096 bytes instead of 512 bytes, the automated sector size detection algorithm of ZFS might detect 512 bytes because the backwards compatibility with legacy systems. This would result in degraded performance. To make sure a correct sector size is used, the {{ic|<nowiki>ashift=12</nowiki>}} option should be used (See the [http://zfsonlinux.org/faq.html#HowDoesZFSonLinuxHandleAdvacedFormatDrives ZFS on Linux FAQ]). The full command would in this case be:<br />
<br />
# zpool create -f -o ashift=12 -m /mnt/data bigdata \<br />
raidz \<br />
ata-ST3000DM001-9YN166_S1F0KDGY \<br />
ata-ST3000DM001-9YN166_S1F0JKRR \<br />
ata-ST3000DM001-9YN166_S1F0KBP8 \<br />
ata-ST3000DM001-9YN166_S1F0JTM1<br />
<br />
=== Verifying pool creation ===<br />
<br />
If the command is successful, there will be no output. Using the {{ic|$ mount}} command will show that the pool is mounted. Using {{ic|# zpool status}} will show that the pool has been created.<br />
<br />
{{hc|# zpool status|<br />
pool: bigdata<br />
state: ONLINE<br />
scan: none requested<br />
config:<br />
<br />
NAME STATE READ WRITE CKSUM<br />
bigdata ONLINE 0 0 0<br />
-0 ONLINE 0 0 0<br />
ata-ST3000DM001-9YN166_S1F0KDGY-part1 ONLINE 0 0 0<br />
ata-ST3000DM001-9YN166_S1F0JKRR-part1 ONLINE 0 0 0<br />
ata-ST3000DM001-9YN166_S1F0KBP8-part1 ONLINE 0 0 0<br />
ata-ST3000DM001-9YN166_S1F0JTM1-part1 ONLINE 0 0 0<br />
<br />
errors: No known data errors<br />
}}<br />
<br />
At this point it would be good to reboot the machine to ensure that the ZFS pool is mounted at boot. It is best to deal with all errors before transferring data.<br />
<br />
=== GRUB-compatible pool creation ===<br />
<br />
By default, ''zpool'' will enable all features on a pool. If {{ic|/boot}} resides on ZFS and when using [[GRUB]], you must only enable read-only, or non-read-only features supported by GRUB ({{ic|lz4_compress}} as of version 2.02.beta2). Otherwise GRUB will not be able to read the pool.<br />
<br />
# zpool create -d \<br />
-o feature@async_destroy=enabled \<br />
-o feature@empty_bpobj=enabled \<br />
-o feature@lz4_compress=enabled \<br />
-o feature@spacemap_histogram=enabled \<br />
-o feature@enabled_txg=enabled \<br />
<pool_name> <vdevs><br />
<br />
{{Tip|As of September 2015, GRUB's development tree supports {{ic|extensible_dataset}}, {{ic|hole_birth}}, {{ic|embedded_data}}, and {{ic|large_blocks}}, making it viable to use a pool with all features enabled, either at create time or by using {{ic|zpool upgrade <pool_name>}}, if {{AUR|grub-git}} is installed.}}<br />
<br />
=== Importing a pool created by id ===<br />
<br />
Eventually a pool may fail to auto mount and you need to import to bring your pool back. Take care to avoid the most obvious solution.<br />
<br />
# ###zpool import zfsdata # Do not do this! Always use -d<br />
<br />
This will import your pools using {{ic|/dev/sd?}} which will lead to problems the next time you rearrange your drives. This may be as simple as rebooting with a USB drive left in the machine, which harkens back to a time when PC's would not boot when a floppy disk was left in a machine. Adapt one of the following commands to import your pool so that pool imports retain the persistence they were created with.<br />
<br />
# zpool import -d /dev/disk/by-id zfsdata<br />
# zpool import -d /dev/disk/by-partlabel zfsdata<br />
# zpool import -d /dev/disk/by-partuuid zfsdata<br />
<br />
== Tuning ==<br />
<br />
=== General ===<br />
Many parameters are available for zfs file systems, you can view a full list with {{ic|zfs get all <pool>}}. Two common ones to adjust are '''atime''' and '''compression'''.<br />
<br />
Atime is enabled by default but for most users, it represents superfluous writes to the zpool and it can be disabled using the zfs command:<br />
# zfs set atime=off <pool><br />
<br />
As an alternative to turning off atime completely, '''relatime''' is available. This brings the default ext4/xfs atime semantics to ZFS, where access time is only updated if the modified time or changed time changes, or if the existing access time has not been updated within the past 24 hours. It is a compromise between atime=off and atime=on. This property ''only'' takes effect if '''atime''' is '''on''':<br />
# zfs set relatime=on <pool><br />
<br />
Compression is just that, transparent compression of data. ZFS supports a few different algorithms, presently lz4 is the default. '''gzip''' is also available for seldom-written yet highly-compressable data; consult the man page for more details. Enable compression using the zfs command:<br />
# zfs set compression=on <pool><br />
<br />
Other options for zfs can be displayed again, using the zfs command:<br />
# zfs get all <pool><br />
<br />
=== Database ===<br />
ZFS, unlike most other file systems, has a variable record size, or what is commonly referred to as a block size. By default, the recordsize on ZFS is 128KiB, which means it will dynamically allocate blocks of any size from 512B to 128KiB depending on the size of file being written. This can often help fragmentation and file access, at the cost that ZFS would have to allocate new 128KiB blocks each time only a few bytes are written to.<br />
<br />
Most RDBMSes work in 8KiB-sized blocks by default. Although the block size is tunable for [[MySQL|MySQL/MariaDB]], [[PostgreSQL]], and [[Oracle]], all three of them use an 8KiB block size ''by default''. For both performance concerns and keeping snapshot differences to a minimum (for backup purposes, this is helpful), it is usually desirable to tune ZFS instead to accommodate the databases, using a command such as:<br />
# zfs set recordsize=8K <pool>/postgres<br />
<br />
These RDBMSes also tend to implement their own caching algorithm, often similar to ZFS's own ARC. In the interest of saving memory, it is best to simply disable ZFS's caching of the database's file data and let the database do its own job:<br />
# zfs set primarycache=metadata <pool>/postgres<br />
<br />
If your pool has no configured log devices, ZFS reserves space on the pool's data disks for its intent log (the ZIL). ZFS uses this for crash recovery, but databases are often syncing their data files to the file system on their own transaction commits anyway. The end result of this is that ZFS will be committing data '''twice''' to the data disks, and it can severely impact performance. You can tell ZFS to prefer to not use the ZIL, and in which case, data is only committed to the file system once. Setting this for non-database file systems, or for pools with configured log devices, can actually ''negatively'' impact the performance, so beware:<br />
# zfs set logbias=throughput <pool>/postgres<br />
<br />
These can also be done at file system creation time, for example:<br />
# zfs create -o recordsize=8K \<br />
-o primarycache=metadata \<br />
-o mountpoint=/var/lib/postgres \<br />
-o logbias=throughput \<br />
<pool>/postgres<br />
<br />
Please note: these kinds of tuning parameters are ideal for specialized applications like RDBMSes. You can easily ''hurt'' ZFS's performance by setting these on a general-purpose file system such as your /home directory.<br />
<br />
=== /tmp ===<br />
If you would like to use ZFS to store your /tmp directory, which may be useful for storing arbitrarily-large sets of files or simply keeping your RAM free of idle data, you can generally improve performance of certain applications writing to /tmp by disabling file system sync. This causes ZFS to ignore an application's sync requests (eg, with {{ic|fsync}} or {{ic|O_SYNC}}) and return immediately. While this has severe application-side data consistency consequences (never disable sync for a database!), files in /tmp are less likely to be important and affected. Please note this does ''not'' affect the integrity of ZFS itself, only the possibility that data an application expects on-disk may not have actually been written out following a crash.<br />
# zfs set sync=disabled <pool>/tmp<br />
<br />
Additionally, for security purposes, you may want to disable '''setuid''' and '''devices''' on the /tmp file system, which prevents some kinds of privilege-escalation attacks or the use of device nodes:<br />
# zfs set setuid=off <pool>/tmp<br />
# zfs set devices=off <pool>/tmp<br />
<br />
Combining all of these for a create command would be as follows:<br />
# zfs create -o setuid=off -o devices=off -o sync=disabled -o mountpoint=/tmp <pool>/tmp<br />
<br />
Please note, also, that if you want /tmp on ZFS, you will need to mask (disable) [[systemd]]'s automatic tmpfs-backed /tmp, else ZFS will be unable to mount your dataset at boot-time or import-time:<br />
# systemctl mask tmp.mount<br />
<br />
=== ZVOLs ===<br />
<br />
ZFS volumes (ZVOLs) can suffer from the same block size-related issues as RDBMSes, but it is worth noting that the default recordsize for ZVOLs is 8KiB already. If possible, it is best to align any partitions contained in a ZVOL to your recordsize (current versions of fdisk and gdisk by default automatically align at 1MiB segments, which works), and file system block sizes to the same size. Other than this, you might tweak the '''recordsize''' to accommodate the data inside the ZVOL as necessary (though 8KiB tends to be a good value for most file systems, even when using 4KiB blocks on that level).<br />
<br />
==== RAIDZ and Advanced Format physical disks ====<br />
<br />
Each block of a ZVOL gets its own parity disks, and if you have physical media with logical block sizes of 4096B, 8192B, or so on, the parity needs to be stored in whole physical blocks, and this can drastically increase the space requirements of a ZVOL, requiring 2× or more physical storage capacity than the ZVOL's logical capacity. Setting the '''recordsize''' to 16k or 32k can help reduce this footprint drastically.<br />
<br />
See [https://github.com/zfsonlinux/zfs/issues/1807 ZFS on Linux issue #1807 for details]<br />
<br />
== Usage ==<br />
<br />
Users can optionally create a dataset under the zpool as opposed to manually creating directories under the zpool. Datasets allow for an increased level of control (quotas for example) in addition to snapshots. To be able to create and mount a dataset, a directory of the same name must not pre-exist in the zpool. To create a dataset, use:<br />
<br />
# zfs create <nameofzpool>/<nameofdataset><br />
<br />
It is then possible to apply ZFS specific attributes to the dataset. For example, one could assign a quota limit to a specific directory within a dataset:<br />
<br />
# zfs set quota=20G <nameofzpool>/<nameofdataset>/<directory><br />
<br />
To see all the commands available in ZFS, use :<br />
<br />
$ man zfs<br />
<br />
or:<br />
<br />
$ man zpool<br />
<br />
=== Scrub ===<br />
<br />
ZFS pools should be scrubbed at least once a week. To scrub the pool:<br />
<br />
# zpool scrub <pool><br />
<br />
To do automatic scrubbing once a week, set the following line in the root crontab:<br />
<br />
{{hc|# crontab -e|<br />
...<br />
30 19 * * 5 zpool scrub <pool><br />
...<br />
}}<br />
<br />
Replace {{ic|<pool>}} with the name of the ZFS pool.<br />
<br />
=== Check zfs pool status ===<br />
<br />
To print a nice table with statistics about the ZFS pool, including and read/write errors, use<br />
<br />
# zpool status -v<br />
<br />
=== Destroy a storage pool ===<br />
<br />
ZFS makes it easy to destroy a mounted storage pool, removing all metadata about the ZFS device. This command destroys any data contained in the pool:<br />
<br />
# zpool destroy <pool><br />
<br />
And now when checking the status:<br />
<br />
{{hc|# zpool status|no pools available}}<br />
<br />
To find the name of the pool, see [[#Check zfs pool status]].<br />
<br />
=== Export a storage pool ===<br />
<br />
If a storage pool is to be used on another system, it will first need to be exported. It is also necessary to export a pool if it has been imported from the archiso as the hostid is different in the archiso as it is in the booted system. The zpool command will refuse to import any storage pools that have not been exported. It is possible to force the import with the {{ic|-f}} argument, but this is considered bad form.<br />
<br />
Any attempts made to import an un-exported storage pool will result in an error stating the storage pool is in use by another system. This error can be produced at boot time abruptly abandoning the system in the busybox console and requiring an archiso to do an emergency repair by either exporting the pool, or adding the {{ic|zfs_force&#61;1}} to the kernel boot parameters (which is not ideal). See [[#On boot the zfs pool does not mount stating: "pool may be in use from other system"]]<br />
<br />
To export a pool,<br />
<br />
# zpool export bigdata<br />
<br />
=== Rename a Zpool ===<br />
Renaming a zpool that is already created is accomplished in 2 steps:<br />
<br />
# zpool export oldname<br />
# zpool import oldname newname<br />
<br />
=== Setting a Different Mount Point ===<br />
The mount point for a given zpool can be moved at will with one command:<br />
# zfs set mountpoint=/foo/bar poolname<br />
<br />
=== Swap volume ===<br />
<br />
ZFS does not allow to use swapfiles, but users can use a ZFS volume (ZVOL) as swap. It is importart to set the ZVOL block size to match the system page size, which can be obtained by the {{ic|getconf PAGESIZE}} command (default on x86_64 is 4KiB). Another option useful for keeping the system running well in low-memory situations is not caching the ZVOL data.<br />
<br />
Create a 8GiB zfs volume:<br />
<br />
# zfs create -V 8G -b $(getconf PAGESIZE) \<br />
-o primarycache=metadata \<br />
-o com.sun:auto-snapshot=false <pool>/swap<br />
<br />
Prepare it as swap partition:<br />
<br />
# mkswap -f /dev/zvol/<pool>/swap<br />
# swapon /dev/zvol/<pool>/swap<br />
<br />
To make it permanent, edit {{ic|/etc/fstab}}. ZVOLs support discard, which can potentially help ZFS's block allocator and reduce fragmentation for all other datasets when/if swap is not full.<br />
<br />
Add a line to {{ic|/etc/fstab}}:<br />
<br />
/dev/zvol/<pool>/swap none swap discard 0 0<br />
<br />
{{Out of date|The hibernate hook is deprecated. Does the limitation still apply?}}<br />
Keep in mind the Hibernate hook must be loaded before filesystems, so using ZVOL as swap will not allow to use hibernate function. If you need hibernate, keep a partition for it.<br />
<br />
Make sure to unmount all ZFS filesystems before rebooting the machine, otherwise any ZFS pools will refuse to be imported:<br />
# zfs umount -a<br />
<br />
=== Automatic snapshots ===<br />
<br />
==== ZFS Automatic Snapshot Service for Linux ====<br />
<br />
The {{AUR|zfs-auto-snapshot-git}} package from [[Arch User Repository|AUR]] provides a shell script to automate the management of snapshots, with each named by date and label (hourly, daily, etc), giving quick and convenient snapshotting of all ZFS datasets. The package also installs cron tasks for quarter-hourly, hourly, daily, weekly, and monthly snapshots. Optionally adjust the --keep parameter from the defaults depending on how far back the snapshots are to go (the monthly script by default keeps data for up to a year).<br />
<br />
To prevent a dataset from being snapshotted at all, set {{ic|1=com.sun:auto-snapshot=false}} on it. Likewise, set more fine-grained control as well by label, if, for example, no monthlies are to be kept on a snapshot, for example, set {{ic|1=com.sun:auto-snapshot:monthly=false}}.<br />
<br />
==== ZFS Snapshot Manager ====<br />
<br />
The {{AUR|zfs-snap-manager}} package from [[Arch User Repository|AUR]] provides a python service that takes daily snapshots from a configurable set of ZFS datasets and cleans them out in a [[wikipedia:Backup_rotation_scheme#Grandfather-father-son|"Grandfather-father-son"]] scheme. It can be configured to e.g. keep 7 daily, 5 weekly, 3 monthly and 2 yearly snapshots. <br />
<br />
The package also supports configurable replication to other machines running ZFS by means of {{ic|zfs send}} and {{ic|zfs receive}}. If the destination machine runs this package as well, it could be configured to keep these replicated snapshots for a longer time. This allows a setup where a source machine has only a few daily snapshots locally stored, while on a remote storage server a much longer retention is available.<br />
<br />
==Troubleshooting==<br />
=== ZPool creation fails ===<br />
If the following error occurs then it can be fixed.<br />
<br />
# the kernel failed to rescan the partition table: 16<br />
# cannot label 'sdc': try using parted(8) and then provide a specific slice: -1<br />
<br />
One reason this can occur is because [https://github.com/zfsonlinux/zfs/issues/2582 ZFS expects pool creation to take less than 1 second]. This is a reasonable assumption under ordinary conditions, but in many situations it may take longer. Each drive will need to be cleared again before another attempt can be made.<br />
<br />
# parted /dev/sda rm 1<br />
# parted /dev/sda rm 1<br />
# dd if=/dev/zero of=/dev/sdb bs=512 count=1<br />
# zpool labelclear /dev/sda<br />
<br />
A brute force creation can be attempted over and over again, and with some luck the ZPool creation will take less than 1 second.<br />
Once cause for creation slowdown can be slow burst read writes on a drive. By reading from the disk in parallell to ZPool creation, it may be possible to increase burst speeds.<br />
<br />
# dd if=/dev/sda of=/dev/null<br />
<br />
This can be done with multiple drives by saving the above command for each drive to a file on separate lines and running <br />
<br />
# cat $FILE | parallel<br />
<br />
Then run ZPool creation at the same time.<br />
<br />
=== ZFS is using too much RAM ===<br />
<br />
By default, ZFS caches file operations ([[wikipedia:Adaptive replacement cache|ARC]]) using up to two-thirds of available system memory on the host. Remember, ZFS is designed for enterprise class storage systems! To adjust the ARC size, add the following to the [[Kernel parameters]] list:<br />
<br />
zfs.zfs_arc_max=536870912 # (for 512MB)<br />
<br />
For a more detailed description, as well as other configuration options, see [http://wiki.gentoo.org/wiki/ZFS#ARC gentoo-wiki:zfs#arc].<br />
<br />
=== Does not contain an EFI label ===<br />
<br />
The following error will occur when attempting to create a zfs filesystem,<br />
<br />
/dev/disk/by-id/<id> does not contain an EFI label but it may contain partition<br />
<br />
The way to overcome this is to use {{ic|-f}} with the zfs create command.<br />
<br />
=== No hostid found ===<br />
<br />
An error that occurs at boot with the following lines appearing before initscript output:<br />
<br />
ZFS: No hostid found on kernel command line or /etc/hostid.<br />
<br />
This warning occurs because the ZFS module does not have access to the spl hosted. There are two solutions, for this. Either place the spl hostid in the [[kernel parameters]] in the boot loader. For example, adding {{ic|1=spl.spl_hostid=0x00bab10c}}.<br />
<br />
The other solution is to make sure that there is a hostid in {{ic|/etc/hostid}}, and then regenerate the initramfs image. Which will copy the hostid into the initramfs image.<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== On boot the zfs pool does not mount stating: "pool may be in use from other system" ===<br />
<br />
==== Unexported pool ====<br />
<br />
If the new installation does not boot because the zpool cannot be imported, chroot into the installation and properly export the zpool. See [[#Emergency chroot repair with archzfs]].<br />
<br />
Once inside the chroot environment, load the ZFS module and force import the zpool,<br />
<br />
# zpool import -a -f<br />
<br />
now export the pool:<br />
<br />
# zpool export <pool><br />
<br />
To see the available pools, use,<br />
<br />
# zpool status<br />
<br />
It is necessary to export a pool because of the way ZFS uses the hostid to track the system the zpool was created on. The hostid is generated partly based on the network setup. During the installation in the archiso the network configuration could be different generating a different hostid than the one contained in the new installation. Once the zfs filesystem is exported and then re-imported in the new installation, the hostid is reset. See [http://osdir.com/ml/zfs-discuss/2011-06/msg00227.html Re: Howto zpool import/export automatically? - msg#00227].<br />
<br />
If ZFS complains about "pool may be in use" after every reboot, properly export pool as described above, and then rebuild ramdisk in normally booted system:<br />
<br />
# mkinitcpio -p linux<br />
<br />
==== Incorrect hostid ====<br />
<br />
Double check that the pool is properly exported. Exporting the zpool clears the hostid marking the ownership. So during the first boot the zpool should mount correctly. If it does not there is some other problem.<br />
<br />
Reboot again, if the zfs pool refuses to mount it means the hostid is not yet correctly set in the early boot phase and it confuses zfs. Manually tell zfs the correct number, once the hostid is coherent across the reboots the zpool will mount correctly.<br />
<br />
Boot using zfs_force and write down the hostid. This one is just an example.<br />
% hostid<br />
0a0af0f8<br />
<br />
This number have to be added to the [[kernel parameters]] as {{ic|spl.spl_hostid&#61;0a0af0f8}}. Another solution is writing the hostid inside the initram image, see the [[Installing Arch Linux on ZFS#After the first boot|installation guide]] explanation about this.<br />
<br />
Users can always ignore the check adding {{ic|zfs_force&#61;1}} in the [[kernel parameters]], but it is not advisable as a permanent solution.<br />
<br />
=== Devices have different sector alignment ===<br />
<br />
Once a drive has become faulted it should be replaced A.S.A.P. with an identical drive.<br />
<br />
# zpool replace bigdata ata-ST3000DM001-9YN166_S1F0KDGY ata-ST3000DM001-1CH166_W1F478BD -f<br />
<br />
but in this instance, the following error is produced:<br />
<br />
cannot replace ata-ST3000DM001-9YN166_S1F0KDGY with ata-ST3000DM001-1CH166_W1F478BD: devices have different sector alignment<br />
<br />
ZFS uses the ashift option to adjust for physical block size. When replacing the faulted disk, ZFS is attempting to use {{ic|<nowiki>ashift=12</nowiki>}}, but the faulted disk is using a different ashift (probably {{ic|<nowiki>ashift=9</nowiki>}}) and this causes the resulting error. <br />
<br />
For Advanced Format Disks with 4KB blocksize, an ashift of 12 is recommended for best performance. See [http://zfsonlinux.org/faq.html#PerformanceConsideration 1.10 What’s going on with performance?] and [http://wiki.illumos.org/display/illumos/ZFS+and+Advanced+Format+disks ZFS and Advanced Format disks].<br />
<br />
Use zdb to find the ashift of the zpool: {{ic|zdb | grep ashift}}, then use the {{ic|-o}} argument to set the ashift of the replacement drive:<br />
<br />
# zpool replace bigdata ata-ST3000DM001-9YN166_S1F0KDGY ata-ST3000DM001-1CH166_W1F478BD -o ashift=9 -f<br />
<br />
Check the zpool status for confirmation:<br />
<br />
{{hc|# zpool status -v|<br />
pool: bigdata<br />
state: DEGRADED<br />
status: One or more devices is currently being resilvered. The pool will<br />
continue to function, possibly in a degraded state.<br />
action: Wait for the resilver to complete.<br />
scan: resilver in progress since Mon Jun 16 11:16:28 2014<br />
10.3G scanned out of 5.90T at 81.7M/s, 20h59m to go<br />
2.57G resilvered, 0.17% done<br />
config:<br />
<br />
NAME STATE READ WRITE CKSUM<br />
bigdata DEGRADED 0 0 0<br />
raidz1-0 DEGRADED 0 0 0<br />
replacing-0 OFFLINE 0 0 0<br />
ata-ST3000DM001-9YN166_S1F0KDGY OFFLINE 0 0 0<br />
ata-ST3000DM001-1CH166_W1F478BD ONLINE 0 0 0 (resilvering)<br />
ata-ST3000DM001-9YN166_S1F0JKRR ONLINE 0 0 0<br />
ata-ST3000DM001-9YN166_S1F0KBP8 ONLINE 0 0 0<br />
ata-ST3000DM001-9YN166_S1F0JTM1 ONLINE 0 0 0<br />
<br />
errors: No known data errors}}<br />
<br />
== Tips and tricks ==<br />
<br />
===Embed the archzfs packages into an archiso===<br />
<br />
Follow the [[Archiso]] steps for creating a fully functional Arch Linux live CD/DVD/USB image.<br />
<br />
Enable the [[Unofficial user repositories#demz-repo-core|demz-repo-core]] repository:<br />
<br />
{{hc|~/archlive/pacman.conf|<nowiki><br />
...<br />
[demz-repo-core]<br />
Server = http://demizerone.com/$repo/$arch<br />
</nowiki>}}<br />
<br />
Add the {{ic|archzfs-git}} group to the list of packages to be installed:<br />
<br />
{{hc|~/archlive/packages.both|<br />
...<br />
archzfs-git<br />
}}<br />
<br />
Complete [[Archiso#Archiso#Build_the_ISO|Build the ISO]] to finally build the iso.<br />
<br />
=== Encryption in ZFS on linux ===<br />
<br />
ZFS on linux does not support encryption directly, but zpools can be created in dm-crypt block devices. Since the zpool is created on the plain-text<br />
abstraction it is possible to have the data encrypted while having all the advantages of ZFS like deduplication, compression, and data robustness.<br />
<br />
dm-crypt, possibly via LUKS, creates devices in {{ic|/dev/mapper}} and their name is fixed. So you just need to change {{ic|zpool create}} commands to<br />
point to that names. The idea is configuring the system to create the {{ic|/dev/mapper}} block devices and import the zpools from there.<br />
Since zpools can be created in multiple devices (raid, mirroring, striping, ...), it is important all the devices are encrypted otherwise the protection<br />
might be partially lost.<br />
<br />
For example, an encrypted zpool can be created using plain dm-crypt (without LUKS) with:<br />
<br />
# cryptsetup --hash=sha512 --cipher=twofish-xts-plain64 --offset=0 \<br />
--key-file=/dev/sdZ --key-size=512 open --type=plain /dev/sdX enc<br />
# zpool create zroot /dev/mapper/enc<br />
<br />
In the case of a root filesystem pool, the {{ic|mkinicpio.conf}} HOOKS line will enable the keyboard for the password, create the devices, and load the pools. It will contain something like:<br />
<br />
HOOKS="... keyboard encrypt zfs ..."<br />
<br />
Since the {{ic|/dev/mapper/enc}} name is fixed no import errors will occur.<br />
<br />
Creating encrypted zpools works fine. But if you need encrypted directories, for example to protect your users' homes, ZFS loses some functionality.<br />
<br />
ZFS will see the encrypted data, not the plain-text abstraction, so compression and deduplication will not work. The reason is that encrypted data has always high entropy making compression ineffective and even from the same input you get different output (thanks to salting) making deduplication impossible.<br />
To reduce the unnecessary overhead it is possible to create a sub-filesystem for each encrypted directory and use [[eCryptfs]] on it.<br />
<br />
For example to have an encrypted home: (the two passwords, encryption and login, must be the same)<br />
# zfs create -o compression=off \<br />
-o dedup=off \<br />
-o mountpoint=/home/<username> \<br />
<zpool>/<username><br />
# useradd -m <username><br />
# passwd <username><br />
# ecryptfs-migrate-home -u <username><br />
<log in user and complete the procedure with ecryptfs-unwrap-passphrase><br />
<br />
=== Emergency chroot repair with archzfs ===<br />
<br />
To get into the ZFS filesystem from live system for maintenance, there are two options:<br />
<br />
# Build custom archiso with ZFS as described in [[#Embed the archzfs packages into an archiso]].<br />
# Boot the latest official archiso and bring up the network. Then enable [[Unofficial_user_repositories#demz-repo-archiso|demz-repo-archiso]] repository inside the live system as usual, sync the pacman package database and install the ''archzfs-git'' package.<br />
<br />
To start the recovery, load the ZFS kernel modules:<br />
<br />
# modprobe zfs<br />
<br />
Import the pool:<br />
<br />
# zpool import -a -R /mnt<br />
<br />
Mount the boot partitions (if any):<br />
<br />
# mount /dev/sda2 /mnt/boot<br />
# mount /dev/sda1 /mnt/boot/efi<br />
<br />
Chroot into the ZFS filesystem:<br />
<br />
# arch-chroot /mnt /bin/bash<br />
<br />
Check the kernel version:<br />
<br />
# pacman -Qi linux<br />
# uname -r<br />
<br />
uname will show the kernel version of the archiso. If they are different, run depmod (in the chroot) with the correct kernel version of the chroot installation:<br />
<br />
# depmod -a 3.6.9-1-ARCH (version gathered from pacman -Qi linux)<br />
<br />
This will load the correct kernel modules for the kernel version installed in the chroot installation.<br />
<br />
Regenerate the ramdisk:<br />
<br />
# mkinitcpio -p linux<br />
<br />
There should be no errors.<br />
<br />
=== Automated build script ===<br />
<br />
{{Deletion|The wiki isn't the place to maintain massive script dumps}}<br />
<br />
The following script may be used to build ZFS and its dependencies automatically.<br />
<br />
The build order of the above is important due to nested dependencies. One can automate the entire process, including downloading the packages with the following shell script. The only requirements for it to work are:<br />
*{{pkg|sudo}} - Note that your user needed sudo rights to {{ic|/usr/bin/clean-chroot-manager}} for the script below to work.<br />
*{{pkg|rsync}} - Needed for moving over the build files.<br />
*{{AUR|cower}} - Needed to grab sources from the AUR.<br />
*{{AUR|clean-chroot-manager}} - Needed to build in a clean chroot and add packages to a local repo.<br />
<br />
Be sure to add the local repo to {{ic|/etc/pacman.conf}} like so:<br />
{{hc|$ tail /etc/pacman.conf|<nowiki><br />
[chroot_local]<br />
SigLevel = Optional TrustAll<br />
Server = file:///path/to/localrepo/defined/below<br />
</nowiki>}}<br />
<br />
{{hc|~/bin/build_zfs|<nowiki><br />
#!/bin/bash<br />
#<br />
# ZFS Builder by graysky<br />
#<br />
<br />
# define the temp space for building here<br />
WORK='/scratch'<br />
<br />
# create this dir and chown it to your user<br />
# this is the local repo which will store your zfs packages<br />
REPO='/var/repo'<br />
<br />
# Add the following entry to /etc/pacman.conf for the local repo<br />
#[chroot_local]<br />
#SigLevel = Optional TrustAll<br />
#Server = file:///path/to/localrepo/defined/above<br />
<br />
for i in rsync cower clean-chroot-manager; do<br />
command -v $i >/dev/null 2>&1 || {<br />
echo "I require $i but it's not installed. Aborting." >&2<br />
exit 1; }<br />
done<br />
<br />
[[ -f ~/.config/clean-chroot-manager.conf ]] &&<br />
. ~/.config/clean-chroot-manager.conf || exit 1<br />
<br />
[[ ! -d "$REPO" ]] &&<br />
echo "Make the dir for your local repo and chown it: $REPO" && exit 1<br />
<br />
[[ ! -d "$WORK" ]] &&<br />
echo "Make a work directory: $WORK" && exit 1<br />
<br />
cd "$WORK"<br />
for i in spl-utils-git spl-git zfs-utils-git zfs-git; do<br />
[[ -d $i ]] && rm -rf $i<br />
cower -d $i<br />
done<br />
<br />
for i in spl-utils-git spl-git zfs-utils-git zfs-git; do<br />
cd "$WORK/$i"<br />
sudo ccm s<br />
done<br />
<br />
rsync -auvxP "$CHROOTPATH/root/repo/" "$REPO"<br />
</nowiki>}}<br />
<br />
When ZFS is used as a data drive and boot support is not needed, these two shell scripts will build and remove all zfs packages. The only requirements are {{pkg|sudo}}, {{pkg|git}}, and answering a couple of prompts. On each kernel upgrade you remove ZFS with {{ic|zfsun.sh}}, update, and install ZFS with {{ic|zfsbuild.sh}}.<br />
{{hc|~/build/zfspkg/zfsbuild.sh|<nowiki><br />
#!/usr/bin/bash<br />
#<br />
# 2015-07-17 zfsbuild.sh by severach for AUR 4<br />
# 2015-08-08 AUR4 -> AUR, added git pull, safer AUR 3.5 update folder<br />
# Adapted from ZFS Builder by graysky<br />
# place this in a user home folder.<br />
# I recommend ~/build/zfspkg/. Do not name the folder 'zfs'.<br />
<br />
# 1 to add conflicts=(linux>,linux<) which offers automatic removal on upgrade.<br />
# Manual removal with zfsun.sh is preferred.<br />
_opt_AutoRemove=0<br />
_opt_ZFSPool='zfsdata'<br />
#_opt_ZFSbyid='/dev/disk/by-partlabel'<br />
_opt_ZFSbyid='/dev/disk/by-id'<br />
# '' for manual answer to prompts. --noconfirm to go ahead and do it all.<br />
_opt_AutoInstall='' #--noconfirm'<br />
<br />
# Multiprocessor compile enabled!<br />
# Huuuuuuge performance improvement. Watch in htop.<br />
# An E3-1245 can peg all 8 processors.<br />
#1 [|||||||||||||||||||||||||96.2%]<br />
#2 [|||||||||||||||||||||||||97.6%]<br />
#3 [|||||||||||||||||||||||||95.7%]<br />
#4 [|||||||||||||||||||||||||96.7%]<br />
#5 [|||||||||||||||||||||||||95.7%]<br />
#6 [|||||||||||||||||||||||||97.1%]<br />
#7 [|||||||||||||||||||||||||98.6%]<br />
#8 [|||||||||||||||||||||||||96.2%]<br />
#Mem[||| 596/31974MB]<br />
#Swp[ 0/0MB]<br />
<br />
set -u<br />
set -e<br />
<br />
if [ "${EUID}" -eq 0 ]; then<br />
echo "This script must NOT be run as root"<br />
sleep 1<br />
exit 1<br />
fi<br />
<br />
for i in 'sudo' 'git'; do<br />
command -v "${i}" >/dev/null 2>&1 || {<br />
echo "I require ${i} but it's not installed. Aborting." 1>&2<br />
exit 1; }<br />
done<br />
<br />
cd "$(dirname "$0")"<br />
OPWD="$(pwd)"<br />
for cwpackage in 'spl-utils-git' 'spl-git' 'zfs-utils-git' 'zfs-git'; do<br />
#cower -dc -f "${cwpackage}"<br />
if [ -d "${cwpackage}" -a ! -d "${cwpackage}/.git" ]; then<br />
echo "${cwpackage}: Convert AUR3.5 to AUR4"<br />
cd "${cwpackage}"<br />
git clone "https://aur.archlinux.org/${cwpackage}.git/" "${cwpackage}.temp"<br />
cd "${cwpackage}.temp"<br />
mv '.git' ..<br />
cd ..<br />
rm -rf "${cwpackage}.temp"<br />
cd ..<br />
fi<br />
if [ -d "${cwpackage}" ]; then<br />
echo "${cwpackage}: Update local copy"<br />
cd "${cwpackage}"<br />
git fetch<br />
git reset --hard 'origin/master'<br />
git pull # this line was missed in previous versions<br />
else<br />
echo "${cwpackage}: Clone to new folder"<br />
git clone "https://aur.archlinux.org/${cwpackage}.git/" <br />
cd "${cwpackage}"<br />
fi<br />
sed -i -e 's:^\s\+make$:'"& -s -j $(nproc):g" 'PKGBUILD'<br />
if [ "${_opt_AutoRemove}" -ne 0 ]; then<br />
sed -i -e 's:^conflicts=(.*$: &\n_kernelversionsmall="`uname -r | cut -d - -f 1`"\nconflicts+=("linux>${_kernelversionsmall}" "linux<${_kernelversionsmall}")\n:g' 'PKGBUILD'<br />
fi<br />
if ! makepkg -sCcfi ${_opt_AutoInstall}; then<br />
cd "${OPWD}"<br />
break<br />
fi<br />
#rm -rf 'zfs' 'spl'<br />
cd "${OPWD}"<br />
done<br />
which fsck.zfs<br />
if [ "$?" -eq 0 ]; then<br />
sudo mkinitcpio -p 'linux' # Stores fsck.zfs into the initrd image. I don't know why it would be needed.<br />
fi<br />
#sudo zpool import "${_opt_ZFSPool}" # Don't do this or zpool will mount via /dev/sd?, which you won't like!<br />
sudo zpool import -d "${_opt_ZFSbyid}" "${_opt_ZFSPool}"<br />
sudo zpool status<br />
sudo -k<br />
</nowiki>}}<br />
<br />
{{hc|~/build/zfspkg/zfsun.sh|<nowiki><br />
#!/usr/bin/bash<br />
<br />
# 2015-07-17 zfs uninstaller by severach for AUR4<br />
# Removing ZFS forgets to unmount the pools, which might be desirable if you're<br />
# running ZFS on the root file system.<br />
<br />
_opt_ZFSFolder='/home/zfsdata/foo'<br />
_opt_ZFSPool='zfsdata'<br />
<br />
if [ "${EUID}" -ne 0 ]; then<br />
echo 'Must be root, try sudo !!'<br />
sleep 1<br />
exit 1<br />
fi<br />
<br />
systemctl stop 'smbd.service' # Active shares can lock the mount. You might want to stop nfs too.<br />
zpool export "${_opt_ZFSPool}" # zpool import no longer works with drives that were zfs umount<br />
if [ ! -d "${_opt_ZFSFolder}" ]; then<br />
echo "${_opt_ZFSPool} exported"<br />
pacman -Rc 'spl-utils-git' # This works even if some are already removed.<br />
#pacman -R 'zfs-utils-git' 'spl-git' 'spl-utils-git' 'zfs-git'<br />
else<br />
echo "ZFS didn't unmount"<br />
fi<br />
systemctl start 'smbd.service'<br />
</nowiki>}}<br />
<br />
=== Bindmount ===<br />
<br />
It is not possible too bindmount a directory residing on zfs onto another directory using fstab, because the fstab is read before the zfs pool is ready. To overcome this limitation, a systemd mount unit can be used for the bind mount, as in the following example. Here a bind mount from /mnt/zfspool to /srv/nfs4/music is created. The unit configuration ensures that the zfs pool is ready before the bind mount is created. The name of the mount unit must be equal to the directory mentioned after "Where", replace slashes with minuses. See [[http://utcc.utoronto.ca/~cks/space/blog/linux/SystemdAndBindMounts]] and [[http://utcc.utoronto.ca/~cks/space/blog/linux/SystemdBindMountUnits]] for more details.<br />
{{hc|srv-nfs4-music.mount|<nowiki><br />
[Mount]<br />
What=/mnt/zfspool<br />
Where=/srv/nfs4/music<br />
Type=none<br />
Options=bind<br />
<br />
[Unit]<br />
DefaultDependencies=no<br />
Conflicts=umount.target<br />
Before=local-fs.target umount.target<br />
After=zfs-mount.service<br />
Requires=zfs-mount.service<br />
ConditionPathIsDirectory=/mnt/zfspool<br />
<br />
[Install]<br />
WantedBy=local-fs.target<br />
</nowiki>}}<br />
<br />
== See also ==<br />
<br />
* [[Installing Arch Linux on ZFS]]<br />
* [http://zfsonlinux.org/ ZFS on Linux]<br />
* [http://zfsonlinux.org/faq.html ZFS on Linux FAQ]<br />
* [http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/filesystems-zfs.html FreeBSD Handbook -- The Z File System]<br />
* [http://docs.oracle.com/cd/E19253-01/819-5461/index.html Oracle Solaris ZFS Administration Guide]<br />
* [http://www.solarisinternals.com/wiki/index.php/ZFS_Troubleshooting_Guide Solaris Internals -- ZFS Troubleshooting Guide]<br />
* [http://royal.pingdom.com/2013/06/04/zfs-backup/ Pingdom details how it backs up 5TB of MySQL data every day with ZFS]<br />
<br />
; Aaron Toponce has authored a 17-part blog on ZFS which is an excellent read.<br />
# [https://pthree.org/2012/12/04/zfs-administration-part-i-vdevs/ VDEVs]<br />
# [https://pthree.org/2012/12/05/zfs-administration-part-ii-raidz/ RAIDZ Levels]<br />
# [https://pthree.org/2012/12/06/zfs-administration-part-iii-the-zfs-intent-log/ The ZFS Intent Log]<br />
# [https://pthree.org/2012/12/07/zfs-administration-part-iv-the-adjustable-replacement-cache/ The ARC]<br />
# [https://pthree.org/2012/12/10/zfs-administration-part-v-exporting-and-importing-zpools/ Import/export zpools]<br />
# [https://pthree.org/2012/12/11/zfs-administration-part-vi-scrub-and-resilver/ Scrub and Resilver]<br />
# [https://pthree.org/2012/12/12/zfs-administration-part-vii-zpool-properties/ Zpool Properties]<br />
# [https://pthree.org/2012/12/13/zfs-administration-part-viii-zpool-best-practices-and-caveats/ Zpool Best Practices]<br />
# [https://pthree.org/2012/12/14/zfs-administration-part-ix-copy-on-write/ Copy on Write]<br />
# [https://pthree.org/2012/12/17/zfs-administration-part-x-creating-filesystems/ Creating Filesystems]<br />
# [https://pthree.org/2012/12/18/zfs-administration-part-xi-compression-and-deduplication/ Compression and Deduplication]<br />
# [https://pthree.org/2012/12/19/zfs-administration-part-xii-snapshots-and-clones/ Snapshots and Clones]<br />
# [https://pthree.org/2012/12/20/zfs-administration-part-xiii-sending-and-receiving-filesystems/ Send/receive Filesystems]<br />
# [https://pthree.org/2012/12/21/zfs-administration-part-xiv-zvols/ ZVOLs]<br />
# [https://pthree.org/2012/12/31/zfs-administration-part-xv-iscsi-nfs-and-samba/ iSCSI, NFS, and Samba]<br />
# [https://pthree.org/2013/01/02/zfs-administration-part-xvi-getting-and-setting-properties/ Get/Set Properties]<br />
# [https://pthree.org/2013/01/03/zfs-administration-part-xvii-best-practices-and-caveats/ ZFS Best Practices]</div>Chehrihttps://wiki.archlinux.org/index.php?title=Git&diff=398781Git2015-09-08T12:05:35Z<p>Chehri: AUR4 is now just the AUR.</p>
<hr />
<div>[[Category:Version Control System]]<br />
[[ja:Git]]<br />
[[zh-CN:Git]]<br />
{{Related articles start}}<br />
{{Related|Super Quick Git Guide}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
<br />
[[wikipedia:Git_%28software%29|Git]] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain sources for the Linux kernel, as well as thousands of other projects, including a number of Arch Linux projects. <br />
<br />
== Installation ==<br />
<br />
[[Install]] the {{Pkg|git}} package.<br />
<br />
If you want to use Git's additional tools, make sure you install the required optional dependencies. GUI tools (e.g. ''gitk'' or ''git gui'') require the {{Pkg|tk}} package, or they will refuse to start with an error:<br />
<br />
/usr/bin/gitk: line 3: exec: wish: not found.<br />
<br />
Also, the GUI tools require {{pkg|gsfonts}}, or they will crash with a segmentation fault.<br />
<br />
If you want to use the Git SVN bridge (''git svn'') you will need {{pkg|perl-term-readkey}}, or you will receive the following error: <br />
<br />
Can't locate Term/ReadKey.pm in @INC (you may need to install the Term::ReadKey module)<br />
<br />
== Basic configuration ==<br />
<br />
In order to use Git you need to set at least a name and email:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@foobar.com''"<br />
<br />
See [[#Advanced configuration]] for more settings.<br />
<br />
== Basic usage ==<br />
<br />
This tutorial teaches how to use Git for basic distributed revision control of a project.<br />
<br />
{{Note|An alternative tutorial, which is aimed at users who want to contribute to an existing project, can be found under [[Super Quick Git Guide]].}}<br />
<br />
Git is a distributed version control system, which means that the entire history of changes to a repository is stored locally, in a directory called {{ic|./.git}} in the project directory. The project files which are visible to the user constitute the ''working tree''. These files can be updated to match revisions stored in {{ic|./.git}} using {{ic|git}} commands (e.g. {{ic|git checkout}}), and new revisions can be created in turn by editing these files and running the appropriate {{ic|git}} commands (e.g. {{ic|git commit}}).<br />
<br />
See gitglossary(7) for more complete definitions of the terms used in this tutorial.<br />
<br />
A typical Git workflow is generally:<br />
<br />
# Create a new project or clone a remote one.<br />
# Create a branch to make changes; then commit those changes.<br />
# Consolidate commits for better organization/understanding.<br />
# Merge commits back into the main branch.<br />
# (Optional) Push changes to a remote server.<br />
<br />
=== Local repository ===<br />
<br />
==== Staging operations ====<br />
<br />
'''Initialize''' a new repository. This creates and initializes {{ic|./.git}}:<br />
<br />
$ cd (your project)/<br />
$ git init<br />
<br />
To record the changes to the repository, they must first be added to the ''index'', or ''staging area'', with an operation often also referred to as ''staging''. When you commit changes using {{ic|git commit}}, it is the contents of the index which are committed to the current branch, not the contents of the working tree.<br />
<br />
{{Note|The index is actually a binary file {{ic|.git/index}}, which can be queried with {{ic|git ls-files --stage}}.}}<br />
<br />
To '''add files''' to the index from the working tree:<br />
<br />
$ git add ''file1'' ''file2''<br />
<br />
This records the current state of the files. If the files are subsequently modified, you can run {{ic|git add}} again to "add" the new versions to the index.<br />
<br />
'''Add all''' files:<br />
<br />
$ git add .<br />
<br />
{{Tip|To '''ignore''' some files from, e.g. {{ic|git add .}}, create a {{ic|.gitignore}} file (or files):<br />
<br />
{{hc|.gitignore|<br />
# File I'll likely delete<br />
test-script<br />
<br />
# Ignore all .html files, except 'important.html'<br />
*.html<br />
!important.html<br />
<br />
# Ignore all files recursively in 'DoNotInclude'<br />
DoNotInclude/**<br />
}}<br />
<br />
See [http://git-scm.com/docs/gitignore gitignore(5)] for details.<br />
}}<br />
<br />
'''Remove''' a file from staging ({{ic|--cached}} preserves the actual file(s)):<br />
<br />
$ git rm ''(--cached)'' ''file''<br />
<br />
'''Remove all''' files:<br />
<br />
$ git rm --cached -r .<br />
<br />
Or:<br />
<br />
$ git reset HEAD -- .<br />
<br />
Here, {{ic|HEAD}} is a "symbolic reference" to the current revision.<br />
<br />
'''Rename''' a file:<br />
<br />
$ git mv ''file1'' ''file2''<br />
<br />
{{Note|{{ic|git mv}} is a convenience command, roughly equivalent to {{ic|mv file1 file2}} followed by {{ic|git rm file1}} and {{ic|git add file2}}. Rename detection during merges is based only on content similarity, and ignores the actual commands used to rename files. The broader rationale for this approach, which distinguishes Git from patch-based systems like [[Darcs]], can be found [http://permalink.gmane.org/gmane.comp.version-control.git/217 here].}}<br />
<br />
'''List''' files:<br />
<br />
$ git ls-files<br />
<br />
By default this shows files in the staging area ({{ic|--cached}} files).<br />
<br />
==== Commit changes ====<br />
<br />
Once the content to be recorded is ''staged'', '''commit''' them with:<br />
<br />
$ git commit -m "''First commit.''"<br />
<br />
The {{ic|-m (''--message)}}'' option is for a short message: if omitted, the preset editor will be spawned to allow entering a longer message.<br />
<br />
{{Tip|<br />
* Always commit small changes frequently and with meaningful messages.<br />
* To '''add''' all the modified files to the index, '''and commit''' them in a single command ({{ic|-a}} stands for {{ic|--all}}):<br />
<br />
$ git commit -am "''First commit.''"<br />
}}<br />
<br />
'''Edit''' the commit message for the last commit. This also amends the commit with any files which have been newly staged:<br />
<br />
$ git commit --amend -m "''Message.''"<br />
<br />
Many of the commands in this article take commits as arguments. A commit can be identified by any of the following:<br />
<br />
* Its 40-digit SHA-1 hash (the first 7 digits are usually sufficient to identify it uniquely)<br />
* Any commit label such as a branch or tag name<br />
* The label {{ic|HEAD}} always refers to the currently checked-out commit (usually the head of the branch, unless you used ''git checkout'' to jump back in history to an old commit)<br />
* Any of the above plus {{ic|~}} to refer to previous commits. For example, {{ic|HEAD~}} refers to one commit before {{ic|HEAD}} and {{ic|HEAD~5}} refers to five commits before {{ic|HEAD}}.<br />
<br />
==== View changes ====<br />
<br />
'''Show differences''' between commits:<br />
<br />
$ git diff HEAD HEAD~3<br />
<br />
or between staging area and working tree:<br />
<br />
$ git diff<br />
<br />
'''Get''' a general '''overview''' of the changes:<br />
<br />
$ git status<br />
<br />
'''View history''' of changes (where "''-N''" is the number of latest commits):<br />
<br />
$ git log -p ''(-N)''<br />
<br />
==== Branch a repository ====<br />
<br />
Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch. '''Create''' a branch, whose name accurately reflects its purpose:<br />
<br />
$ git branch ''help-section-addition''<br />
<br />
'''List''' branches:<br />
<br />
$ git branch<br />
<br />
'''Switch''' branches:<br />
<br />
$ git checkout ''branch''<br />
<br />
'''Create and switch''':<br />
<br />
$ git checkout -b ''branch''<br />
<br />
'''Merge''' a branch back to the master branch:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
The changes will be merged if they do not conflict. Otherwise, Git will print an error message, and annotate files in the working tree to record the conflicts. The annotations can be displayed with {{ic|git diff}}. Conflicts are resolved by editing the files to remove the annotations, and committing the final version. See [[#Dealing with merges]] below.<br />
<br />
When done with a branch, '''delete''' it with:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== Collaboration ===<br />
<br />
==== Adopting a good etiquette ====<br />
<br />
* When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.<br />
* Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the [[#History and versioning|log]] of the repository.<br />
* When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.<br />
* If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.<br />
<br />
==== Clone a repository ====<br />
<br />
To begin contributing to a project, '''clone''' its repository:<br />
<br />
$ git clone ''location'' ''folder''<br />
<br />
{{ic|''location''}} can be either a path or network address. Also, when cloning is done, the location is recorded so just a {{ic|git pull}} will be needed later.<br />
<br />
==== Pull requests ====<br />
<br />
After making and committing some changes, the contributor can ask the original author to merge them. This is called a ''pull request''. To '''pull''':<br />
<br />
$ git pull ''location'' master<br />
<br />
The ''pull'' command combines both ''fetching'' and ''merging''. If there are conflicts (e.g. the original author made changes in the same time span), then it will be necessary to manually fix them.<br />
<br />
Alternatively, the original author can '''pick''' the '''changes''' wanting to be incorporated. Using the ''fetch'' option (and ''log'' option with a special {{ic|FETCH_HEAD}} symbol), the contents of the pull request can be viewed before deciding what to do:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== Using remotes ====<br />
<br />
Remotes are aliases for tracked remote repositories. A ''label'' is created defining a location. These labels are used to identify frequently accessed repositories. '''Create''' a remote:<br />
<br />
$ git remote add ''label'' ''location''<br />
<br />
'''Fetch''' a remote:<br />
<br />
$ git fetch ''label''<br />
<br />
'''Show differences''' between master and a remote master:<br />
<br />
$ git log -p master..''label''/master<br />
<br />
'''View''' remotes for the current repository:<br />
<br />
$ git remote -v<br />
<br />
When defining a remote that is a parent of the fork (the project lead), it is defined as ''upstream''.<br />
<br />
==== Push to a repository ====<br />
<br />
After being given rights from the original authors, '''push''' changes with:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
When ''git clone'' is performed, it records the original location and gives it a remote name of {{ic|origin}}. So what '''typically''' is done is this:<br />
<br />
$ git push origin master<br />
<br />
If the {{ic|--set-upstream}} option is used, the location is recorded so the next time just a {{ic|git push}} is necessary.<br />
<br />
==== Dealing with merges ====<br />
<br />
See [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts Basic Merge Conflicts] in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the {{ic|--abort}} command (e.g. {{ic|git merge --abort}} or {{ic|git pull --abort}}).<br />
<br />
==== Send patch to mailing list ====<br />
<br />
If you want to send patches directly to a mailing list, you have to install the following packages: {{Pkg|perl-authen-sasl}}, {{Pkg|perl-net-smtp-ssl}} and {{Pkg|perl-mime-tools}}.<br />
<br />
Make sure you have configured you username and e-mail address, see [[#Basic configuration]].<br />
<br />
'''Configure''' your '''e-mail''' settings:<br />
<br />
$ git config --global sendemail.smtpserver ''smtp.gmail.com''<br />
$ git config --global sendemail.smtpserverport ''587''<br />
$ git config --global sendemail.smtpencryption ''tls''<br />
$ git config --global sendemail.smtpuser ''foobar@gmail.com''<br />
<br />
Now you should be able to '''send''' the '''patch''' to the mailing list (see also [http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches]):<br />
<br />
$ git add ''filename''<br />
$ git commit -s<br />
$ git send-email --to=''openembedded-core@lists.openembedded.org'' --confirm=always -M -1<br />
<br />
=== History and versioning ===<br />
<br />
==== Searching the history ====<br />
<br />
{{ic|git log}} will give the history with a commit checksum, author, date, and the short message. The ''checksum'' is the "object name" of a commit object, typically a 40-character SHA-1 hash. For '''history''' with a '''long message''' (where the "''checksum''" can be truncated, as long as it is unique):<br />
<br />
$ git show (''checksum'')<br />
<br />
'''Search''' for ''pattern'' in tracked files:<br />
<br />
$ git grep ''pattern''<br />
<br />
'''Search''' in '''{{ic|.c}}''' and '''{{ic|.h}}''' files:<br />
<br />
$ git grep ''pattern'' -- '*.[ch]'<br />
<br />
==== Versioning for release ====<br />
<br />
'''Tag''' commits for versioning:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
''Tagging'' is generally done for [https://www.drupal.org/node/1066342 releasing/versioning] but it can be any string. Generally annotated tags are used, because they get added to the Git database. '''Tag''' the '''current''' commit with:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
'''List''' tags:<br />
<br />
$ git tag -l<br />
<br />
'''Delete''' a tag:<br />
<br />
$ git tag -d 2.08<br />
<br />
'''Update remote''' tags with a separate:<br />
<br />
$ git push --tags<br />
<br />
==== Organizing commits ====<br />
<br />
Before submitting a pull request it may be desirable to '''consolidate/organize''' the commits. This is done with the ''git rebase'' {{ic|--interactive}} option:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
This will open the editor with a summary of all the commits in the range specified; in this case including the newest ({{ic|HEAD}}) back to, but excluding, commit {{ic|''checksum''}}. Or to use a number notation, use for example {{ic|HEAD~3}}, which will rebase the last three commits:<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
Editing the action in the first column will dictate how the rebase will be done. The options are:<br />
<br />
* {{ic|pick}} — Apply this commit as is (the default).<br />
* {{ic|edit}} — Edit files and/or commit message.<br />
* {{ic|reword}} — Edit commit message.<br />
* {{ic|squash}} — Merge/fold into previous commit.<br />
* {{ic|fixup}} — Merge/fold into previous commit discarding its message.<br />
<br />
The commits can be re-ordered or erased from the history (but be very careful with these). After editing the file, Git will perform the specified actions; if prompted to resolve merge problems, fix them and continue with {{ic|git rebase --continue}} or back out with the {{ic|git rebase --abort}} command.<br />
<br />
{{Note|Squashing commits is only used for local commits, it will cause troubles on a repository that is shared by other people.}}<br />
<br />
== Advanced configuration ==<br />
<br />
Git reads its configuration from a few INI-type configuration files:<br />
<br />
* Each repository contains a {{ic|.git/config}} file for specific configuration.<br />
* Each user has a {{ic|$HOME/.gitconfig}} file for fallback values.<br />
* {{ic|/etc/gitconfig}} is used for system-wide defaults.<br />
<br />
These files can be edited directly, but the usual method is to use ''git config'', as shown in the examples below.<br />
<br />
List the currently set variables:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
Set the default editor from [[vim]] to [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
Set the default push action:<br />
<br />
$ git config --global push.default simple<br />
<br />
Set a different tool for ''git difftool'' (''meld'' by default):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
See [https://www.kernel.org/pub/software/scm/git/docs/git-config.html git-config(1)] and [http://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration] for more information.<br />
<br />
=== Speeding up SSH ===<br />
<br />
Often if you find yourself pushing constantly to a few common servers, you may wish to remove the hassle of setting your username for each repository. <br />
<br />
If you do not already have the keys created, make them now.<br />
<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/aur -C "''user@domain.com''"<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/github -C "''user@domain.com''"<br />
<br />
Add the resulting public keys to your accounts.<br />
<br />
Additionally, reusing the same SSH connection will drastically improve the time ''git push'' takes:<br />
<br />
$ mkdir -p ~/.ssh/sockets/<br />
<br />
You may wish to adjust the {{ic|ServerAliveInterval}} depending on your connection.<br />
<br />
{{hc|~/.ssh/config|<br />
Host *<br />
ControlMaster auto<br />
ControlPath ~/.ssh/sockets/%r@%h-%p<br />
ControlPersist 8760h<br />
'''ServerAliveInterval 5'''<br />
ServerAliveCountMax 1<br />
TCPKeepAlive yes<br />
<br />
Host aur.archlinux.org<br />
IdentityFile ~/.ssh/aur<br />
User aur<br />
Port 22<br />
<br />
Host github.com<br />
IdentityFile ~/.ssh/github<br />
User [username here]<br />
}}<br />
<br />
=== Protocol Defaults ===<br />
<br />
If you are running a multiplexed SSH connection as shown above, Git over SSH might be faster than HTTPS. Also, some servers (like the AUR) only allow pushing via SSH. For example, the following config will set Git over SSH for any repository hosted on the AUR.<br />
<br />
{{hc|~/.gitconfig|<br />
<br />
[url "ssh://aur@aur.archlinux.org/"]<br />
insteadOf &#61; https://aur.archlinux.org/<br />
insteadOf &#61; http://aur.archlinux.org/<br />
insteadOf &#61; git://aur.archlinux.org/<br />
}}<br />
<br />
=== Bash completion ===<br />
<br />
In order to enable Bash completion, source {{ic|/usr/share/git/completion/git-completion.bash}} in a [[Bash#Configuration_files|Bash startup file]]. Alternatively, install {{pkg|bash-completion}}.<br />
<br />
=== Git prompt ===<br />
<br />
The Git package comes with a prompt script. To enable it, source the {{ic|/usr/share/git/completion/git-prompt.sh}} script in a [[Autostarting#Shells|shell startup file]], then set a custom prompt with the {{ic|%s}} parameter:<br />
<br />
* For [[Bash]]: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* For [[zsh]]: {{ic|1=PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Shell variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || '''+''' for staged, '''*''' if unstaged. <br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || '''$''' if something is stashed.<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || '''%''' if there are untracked files.<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' behind, ahead, or diverged from upstream.<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} will need to be set to {{ic|auto}} for changes to take effect.<br />
<br />
{{Note|If you experience that {{ic|$(__git_ps1)}} returns {{ic|((unknown))}}, then there is a {{ic|.git}} folder in your current directory which does not contain any repository, and therefore Git does not recognize it. This can, for example, happen if you mistake Git's configuration file to be {{ic|~/.git/config}} instead of {{ic|~/.gitconfig}}.}}<br />
<br />
== Advanced usage ==<br />
<br />
To get an idea of the amount of work done:<br />
<br />
$ git diff --stat<br />
<br />
''git log'' with forking representation:<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
''git log'' graph alias (i.e. ''git graph'' will show a decorated version):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
Reset to previous commit (very dangerous, erases everything to specified commit):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
If a repository address gets changed, its remote location will need to be updated:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):<br />
<br />
$ git commit -s<br />
<br />
Signed-off-by automatically append to patches (when using {{ic|git format-patch ''commit''}}):<br />
<br />
$ git config --local format.signoff true<br />
<br />
Commit specific parts of files that have changed. This is useful if there are a large number of changes made that would be best split into several commits:<br />
<br />
$ git add -p<br />
<br />
=== Working with a non-master branch ===<br />
<br />
Occasionally a maintainer will ask that work be done on a branch. These branches are often called {{ic|devel}} or {{ic|testing}}. Begin by cloning the repository.<br />
<br />
To enter another branch beside master (''git clone'' only shows master branch but others still exist, {{ic|git branch -a}} to show):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
Now edit normally; however to keep the repository tree in sync be sure to use both:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
== Git server ==<br />
<br />
How to set up connecting to repositories using varying protocols.<br />
<br />
=== SSH ===<br />
<br />
To use the SSH protocol, first set up a public SSH key; for that follow the guide at [[SSH keys]]. To set up a SSH server, follow the [[SSH]] guide.<br />
<br />
With SSH working and a key generated, paste the contents of {{ic|~/.ssh/id_rsa.pub}} to {{ic|~/.ssh/authorized_keys}} (be sure it is all on one line). Now the Git repository can be accessed with SSH by doing:<br />
<br />
$ git clone ''user''@''foobar.com'':''my_repository''.git<br />
<br />
You should now get an SSH yes/no question, if you have the SSH client setting {{ic|StrictHostKeyChecking}} set to {{ic|ask}} (the default). Type {{ic|yes}} followed by {{ic|Enter}}. Then you should have your repository checked out. Because this is with SSH, you also have commit rights now.<br />
<br />
To modify an existing repository to use SSH, the remote location will need to be redefined:<br />
<br />
$ git remote set-url origin git@localhost:''my_repository''.git<br />
<br />
Connecting on a port other than 22 can be configured on a per-host basis in {{ic|/etc/ssh/ssh_config}} or {{ic|~/.ssh/config}}. To set up ports for a repository, if the repository is in {{ic|~/}} and using 443 for the port:<br />
<br />
{{hc|~/.git/config|2=<br />
[remote "origin"]<br />
url = ssh://''user''@''foobar''.com:443/~''my_repository''/repo.git<br />
}}<br />
<br />
=== Smart HTTP ===<br />
<br />
Git is able to use the HTTP(S) protocol as efficiently as the SSH or Git protocols, by utilizing the git-http-backend. Furthermore it is not only possible to clone or pull from repositories, but also to push into repositories over HTTP(S).<br />
<br />
The setup for this is rather simple as all you need to have installed is the Apache web server ({{pkg|apache}}, with {{ic|mod_cgi}}, {{ic|mod_alias}}, and {{ic|mod_env}} enabled) and of course, {{pkg|git}}.<br />
<br />
Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at:<br />
<br />
{{hc|/etc/httpd/conf/httpd.conf|<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
}}<br />
<br />
This assumes your Git repositories are located at {{ic|/srv/git}} and that you want to access them via something like: {{ic|<nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>}}.<br />
<br />
{{Note|Make sure that Apache can read and write to your repositories.}}<br />
<br />
For more detailed documentation, visit the following links:<br />
* http://progit.org/2010/03/04/smart-http.html<br />
* https://www.kernel.org/pub/software/scm/git/docs/v1.7.10.1/git-http-backend.html<br />
<br />
=== Git ===<br />
<br />
{{Note|The Git protocol only allows read access.}}<br />
<br />
[[start|Start and enable]] {{ic|git-daemon.socket}}.<br />
<br />
The daemon is started with the following options:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
Repositories placed in {{ic|/srv/git/}} will be recognized by the daemon. Clients can connect with something similar to:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== Setting access rights ===<br />
<br />
To restrict read and/or write access, use standard Unix permissions. Refer to http://sitaramc.github.com/gitolite/doc/overkill.html{{Dead link|2013|11|06}} ([https://web.archive.org/web/20111004134500/http://sitaramc.github.com/gitolite/doc/overkill.html archive.org mirror]) for more information.<br />
<br />
For fine-grained access management, refer to [[gitolite]] and [[gitosis]].<br />
<br />
== See also ==<br />
<br />
* [http://git-scm.com/book Pro Git book]<br />
* [http://gitref.org/ Git Reference]<br />
* https://www.kernel.org/pub/software/scm/git/docs/<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request Git overall]<br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git overall2]<br />
* https://wiki.videolan.org/Git<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols offered by GitHub]</div>Chehrihttps://wiki.archlinux.org/index.php?title=Git&diff=398780Git2015-09-08T12:04:31Z<p>Chehri: Changed example to use the AUR.</p>
<hr />
<div>[[Category:Version Control System]]<br />
[[ja:Git]]<br />
[[zh-CN:Git]]<br />
{{Related articles start}}<br />
{{Related|Super Quick Git Guide}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
<br />
[[wikipedia:Git_%28software%29|Git]] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain sources for the Linux kernel, as well as thousands of other projects, including a number of Arch Linux projects. <br />
<br />
== Installation ==<br />
<br />
[[Install]] the {{Pkg|git}} package.<br />
<br />
If you want to use Git's additional tools, make sure you install the required optional dependencies. GUI tools (e.g. ''gitk'' or ''git gui'') require the {{Pkg|tk}} package, or they will refuse to start with an error:<br />
<br />
/usr/bin/gitk: line 3: exec: wish: not found.<br />
<br />
Also, the GUI tools require {{pkg|gsfonts}}, or they will crash with a segmentation fault.<br />
<br />
If you want to use the Git SVN bridge (''git svn'') you will need {{pkg|perl-term-readkey}}, or you will receive the following error: <br />
<br />
Can't locate Term/ReadKey.pm in @INC (you may need to install the Term::ReadKey module)<br />
<br />
== Basic configuration ==<br />
<br />
In order to use Git you need to set at least a name and email:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@foobar.com''"<br />
<br />
See [[#Advanced configuration]] for more settings.<br />
<br />
== Basic usage ==<br />
<br />
This tutorial teaches how to use Git for basic distributed revision control of a project.<br />
<br />
{{Note|An alternative tutorial, which is aimed at users who want to contribute to an existing project, can be found under [[Super Quick Git Guide]].}}<br />
<br />
Git is a distributed version control system, which means that the entire history of changes to a repository is stored locally, in a directory called {{ic|./.git}} in the project directory. The project files which are visible to the user constitute the ''working tree''. These files can be updated to match revisions stored in {{ic|./.git}} using {{ic|git}} commands (e.g. {{ic|git checkout}}), and new revisions can be created in turn by editing these files and running the appropriate {{ic|git}} commands (e.g. {{ic|git commit}}).<br />
<br />
See gitglossary(7) for more complete definitions of the terms used in this tutorial.<br />
<br />
A typical Git workflow is generally:<br />
<br />
# Create a new project or clone a remote one.<br />
# Create a branch to make changes; then commit those changes.<br />
# Consolidate commits for better organization/understanding.<br />
# Merge commits back into the main branch.<br />
# (Optional) Push changes to a remote server.<br />
<br />
=== Local repository ===<br />
<br />
==== Staging operations ====<br />
<br />
'''Initialize''' a new repository. This creates and initializes {{ic|./.git}}:<br />
<br />
$ cd (your project)/<br />
$ git init<br />
<br />
To record the changes to the repository, they must first be added to the ''index'', or ''staging area'', with an operation often also referred to as ''staging''. When you commit changes using {{ic|git commit}}, it is the contents of the index which are committed to the current branch, not the contents of the working tree.<br />
<br />
{{Note|The index is actually a binary file {{ic|.git/index}}, which can be queried with {{ic|git ls-files --stage}}.}}<br />
<br />
To '''add files''' to the index from the working tree:<br />
<br />
$ git add ''file1'' ''file2''<br />
<br />
This records the current state of the files. If the files are subsequently modified, you can run {{ic|git add}} again to "add" the new versions to the index.<br />
<br />
'''Add all''' files:<br />
<br />
$ git add .<br />
<br />
{{Tip|To '''ignore''' some files from, e.g. {{ic|git add .}}, create a {{ic|.gitignore}} file (or files):<br />
<br />
{{hc|.gitignore|<br />
# File I'll likely delete<br />
test-script<br />
<br />
# Ignore all .html files, except 'important.html'<br />
*.html<br />
!important.html<br />
<br />
# Ignore all files recursively in 'DoNotInclude'<br />
DoNotInclude/**<br />
}}<br />
<br />
See [http://git-scm.com/docs/gitignore gitignore(5)] for details.<br />
}}<br />
<br />
'''Remove''' a file from staging ({{ic|--cached}} preserves the actual file(s)):<br />
<br />
$ git rm ''(--cached)'' ''file''<br />
<br />
'''Remove all''' files:<br />
<br />
$ git rm --cached -r .<br />
<br />
Or:<br />
<br />
$ git reset HEAD -- .<br />
<br />
Here, {{ic|HEAD}} is a "symbolic reference" to the current revision.<br />
<br />
'''Rename''' a file:<br />
<br />
$ git mv ''file1'' ''file2''<br />
<br />
{{Note|{{ic|git mv}} is a convenience command, roughly equivalent to {{ic|mv file1 file2}} followed by {{ic|git rm file1}} and {{ic|git add file2}}. Rename detection during merges is based only on content similarity, and ignores the actual commands used to rename files. The broader rationale for this approach, which distinguishes Git from patch-based systems like [[Darcs]], can be found [http://permalink.gmane.org/gmane.comp.version-control.git/217 here].}}<br />
<br />
'''List''' files:<br />
<br />
$ git ls-files<br />
<br />
By default this shows files in the staging area ({{ic|--cached}} files).<br />
<br />
==== Commit changes ====<br />
<br />
Once the content to be recorded is ''staged'', '''commit''' them with:<br />
<br />
$ git commit -m "''First commit.''"<br />
<br />
The {{ic|-m (''--message)}}'' option is for a short message: if omitted, the preset editor will be spawned to allow entering a longer message.<br />
<br />
{{Tip|<br />
* Always commit small changes frequently and with meaningful messages.<br />
* To '''add''' all the modified files to the index, '''and commit''' them in a single command ({{ic|-a}} stands for {{ic|--all}}):<br />
<br />
$ git commit -am "''First commit.''"<br />
}}<br />
<br />
'''Edit''' the commit message for the last commit. This also amends the commit with any files which have been newly staged:<br />
<br />
$ git commit --amend -m "''Message.''"<br />
<br />
Many of the commands in this article take commits as arguments. A commit can be identified by any of the following:<br />
<br />
* Its 40-digit SHA-1 hash (the first 7 digits are usually sufficient to identify it uniquely)<br />
* Any commit label such as a branch or tag name<br />
* The label {{ic|HEAD}} always refers to the currently checked-out commit (usually the head of the branch, unless you used ''git checkout'' to jump back in history to an old commit)<br />
* Any of the above plus {{ic|~}} to refer to previous commits. For example, {{ic|HEAD~}} refers to one commit before {{ic|HEAD}} and {{ic|HEAD~5}} refers to five commits before {{ic|HEAD}}.<br />
<br />
==== View changes ====<br />
<br />
'''Show differences''' between commits:<br />
<br />
$ git diff HEAD HEAD~3<br />
<br />
or between staging area and working tree:<br />
<br />
$ git diff<br />
<br />
'''Get''' a general '''overview''' of the changes:<br />
<br />
$ git status<br />
<br />
'''View history''' of changes (where "''-N''" is the number of latest commits):<br />
<br />
$ git log -p ''(-N)''<br />
<br />
==== Branch a repository ====<br />
<br />
Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch. '''Create''' a branch, whose name accurately reflects its purpose:<br />
<br />
$ git branch ''help-section-addition''<br />
<br />
'''List''' branches:<br />
<br />
$ git branch<br />
<br />
'''Switch''' branches:<br />
<br />
$ git checkout ''branch''<br />
<br />
'''Create and switch''':<br />
<br />
$ git checkout -b ''branch''<br />
<br />
'''Merge''' a branch back to the master branch:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
The changes will be merged if they do not conflict. Otherwise, Git will print an error message, and annotate files in the working tree to record the conflicts. The annotations can be displayed with {{ic|git diff}}. Conflicts are resolved by editing the files to remove the annotations, and committing the final version. See [[#Dealing with merges]] below.<br />
<br />
When done with a branch, '''delete''' it with:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== Collaboration ===<br />
<br />
==== Adopting a good etiquette ====<br />
<br />
* When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.<br />
* Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the [[#History and versioning|log]] of the repository.<br />
* When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.<br />
* If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.<br />
<br />
==== Clone a repository ====<br />
<br />
To begin contributing to a project, '''clone''' its repository:<br />
<br />
$ git clone ''location'' ''folder''<br />
<br />
{{ic|''location''}} can be either a path or network address. Also, when cloning is done, the location is recorded so just a {{ic|git pull}} will be needed later.<br />
<br />
==== Pull requests ====<br />
<br />
After making and committing some changes, the contributor can ask the original author to merge them. This is called a ''pull request''. To '''pull''':<br />
<br />
$ git pull ''location'' master<br />
<br />
The ''pull'' command combines both ''fetching'' and ''merging''. If there are conflicts (e.g. the original author made changes in the same time span), then it will be necessary to manually fix them.<br />
<br />
Alternatively, the original author can '''pick''' the '''changes''' wanting to be incorporated. Using the ''fetch'' option (and ''log'' option with a special {{ic|FETCH_HEAD}} symbol), the contents of the pull request can be viewed before deciding what to do:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== Using remotes ====<br />
<br />
Remotes are aliases for tracked remote repositories. A ''label'' is created defining a location. These labels are used to identify frequently accessed repositories. '''Create''' a remote:<br />
<br />
$ git remote add ''label'' ''location''<br />
<br />
'''Fetch''' a remote:<br />
<br />
$ git fetch ''label''<br />
<br />
'''Show differences''' between master and a remote master:<br />
<br />
$ git log -p master..''label''/master<br />
<br />
'''View''' remotes for the current repository:<br />
<br />
$ git remote -v<br />
<br />
When defining a remote that is a parent of the fork (the project lead), it is defined as ''upstream''.<br />
<br />
==== Push to a repository ====<br />
<br />
After being given rights from the original authors, '''push''' changes with:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
When ''git clone'' is performed, it records the original location and gives it a remote name of {{ic|origin}}. So what '''typically''' is done is this:<br />
<br />
$ git push origin master<br />
<br />
If the {{ic|--set-upstream}} option is used, the location is recorded so the next time just a {{ic|git push}} is necessary.<br />
<br />
==== Dealing with merges ====<br />
<br />
See [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts Basic Merge Conflicts] in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the {{ic|--abort}} command (e.g. {{ic|git merge --abort}} or {{ic|git pull --abort}}).<br />
<br />
==== Send patch to mailing list ====<br />
<br />
If you want to send patches directly to a mailing list, you have to install the following packages: {{Pkg|perl-authen-sasl}}, {{Pkg|perl-net-smtp-ssl}} and {{Pkg|perl-mime-tools}}.<br />
<br />
Make sure you have configured you username and e-mail address, see [[#Basic configuration]].<br />
<br />
'''Configure''' your '''e-mail''' settings:<br />
<br />
$ git config --global sendemail.smtpserver ''smtp.gmail.com''<br />
$ git config --global sendemail.smtpserverport ''587''<br />
$ git config --global sendemail.smtpencryption ''tls''<br />
$ git config --global sendemail.smtpuser ''foobar@gmail.com''<br />
<br />
Now you should be able to '''send''' the '''patch''' to the mailing list (see also [http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches]):<br />
<br />
$ git add ''filename''<br />
$ git commit -s<br />
$ git send-email --to=''openembedded-core@lists.openembedded.org'' --confirm=always -M -1<br />
<br />
=== History and versioning ===<br />
<br />
==== Searching the history ====<br />
<br />
{{ic|git log}} will give the history with a commit checksum, author, date, and the short message. The ''checksum'' is the "object name" of a commit object, typically a 40-character SHA-1 hash. For '''history''' with a '''long message''' (where the "''checksum''" can be truncated, as long as it is unique):<br />
<br />
$ git show (''checksum'')<br />
<br />
'''Search''' for ''pattern'' in tracked files:<br />
<br />
$ git grep ''pattern''<br />
<br />
'''Search''' in '''{{ic|.c}}''' and '''{{ic|.h}}''' files:<br />
<br />
$ git grep ''pattern'' -- '*.[ch]'<br />
<br />
==== Versioning for release ====<br />
<br />
'''Tag''' commits for versioning:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
''Tagging'' is generally done for [https://www.drupal.org/node/1066342 releasing/versioning] but it can be any string. Generally annotated tags are used, because they get added to the Git database. '''Tag''' the '''current''' commit with:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
'''List''' tags:<br />
<br />
$ git tag -l<br />
<br />
'''Delete''' a tag:<br />
<br />
$ git tag -d 2.08<br />
<br />
'''Update remote''' tags with a separate:<br />
<br />
$ git push --tags<br />
<br />
==== Organizing commits ====<br />
<br />
Before submitting a pull request it may be desirable to '''consolidate/organize''' the commits. This is done with the ''git rebase'' {{ic|--interactive}} option:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
This will open the editor with a summary of all the commits in the range specified; in this case including the newest ({{ic|HEAD}}) back to, but excluding, commit {{ic|''checksum''}}. Or to use a number notation, use for example {{ic|HEAD~3}}, which will rebase the last three commits:<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
Editing the action in the first column will dictate how the rebase will be done. The options are:<br />
<br />
* {{ic|pick}} — Apply this commit as is (the default).<br />
* {{ic|edit}} — Edit files and/or commit message.<br />
* {{ic|reword}} — Edit commit message.<br />
* {{ic|squash}} — Merge/fold into previous commit.<br />
* {{ic|fixup}} — Merge/fold into previous commit discarding its message.<br />
<br />
The commits can be re-ordered or erased from the history (but be very careful with these). After editing the file, Git will perform the specified actions; if prompted to resolve merge problems, fix them and continue with {{ic|git rebase --continue}} or back out with the {{ic|git rebase --abort}} command.<br />
<br />
{{Note|Squashing commits is only used for local commits, it will cause troubles on a repository that is shared by other people.}}<br />
<br />
== Advanced configuration ==<br />
<br />
Git reads its configuration from a few INI-type configuration files:<br />
<br />
* Each repository contains a {{ic|.git/config}} file for specific configuration.<br />
* Each user has a {{ic|$HOME/.gitconfig}} file for fallback values.<br />
* {{ic|/etc/gitconfig}} is used for system-wide defaults.<br />
<br />
These files can be edited directly, but the usual method is to use ''git config'', as shown in the examples below.<br />
<br />
List the currently set variables:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
Set the default editor from [[vim]] to [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
Set the default push action:<br />
<br />
$ git config --global push.default simple<br />
<br />
Set a different tool for ''git difftool'' (''meld'' by default):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
See [https://www.kernel.org/pub/software/scm/git/docs/git-config.html git-config(1)] and [http://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration] for more information.<br />
<br />
=== Speeding up SSH ===<br />
<br />
Often if you find yourself pushing constantly to a few common servers, you may wish to remove the hassle of setting your username for each repository. <br />
<br />
If you do not already have the keys created, make them now.<br />
<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/aur -C "''user@domain.com''"<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/github -C "''user@domain.com''"<br />
<br />
Add the resulting public keys to your accounts.<br />
<br />
Additionally, reusing the same SSH connection will drastically improve the time ''git push'' takes:<br />
<br />
$ mkdir -p ~/.ssh/sockets/<br />
<br />
You may wish to adjust the {{ic|ServerAliveInterval}} depending on your connection.<br />
<br />
{{hc|~/.ssh/config|<br />
Host *<br />
ControlMaster auto<br />
ControlPath ~/.ssh/sockets/%r@%h-%p<br />
ControlPersist 8760h<br />
'''ServerAliveInterval 5'''<br />
ServerAliveCountMax 1<br />
TCPKeepAlive yes<br />
<br />
Host aur-dev.archlinux.org<br />
IdentityFile ~/.ssh/aur<br />
User aur<br />
Port 2222<br />
<br />
Host github.com<br />
IdentityFile ~/.ssh/github<br />
User [username here]<br />
}}<br />
<br />
=== Protocol Defaults ===<br />
<br />
If you are running a multiplexed SSH connection as shown above, Git over SSH might be faster than HTTPS. Also, some servers (like the AUR) only allow pushing via SSH. For example, the following config will set Git over SSH for any repository hosted on the AUR.<br />
<br />
{{hc|~/.gitconfig|<br />
<br />
[url "ssh://aur@aur.archlinux.org/"]<br />
insteadOf &#61; https://aur.archlinux.org/<br />
insteadOf &#61; http://aur.archlinux.org/<br />
insteadOf &#61; git://aur.archlinux.org/<br />
}}<br />
<br />
=== Bash completion ===<br />
<br />
In order to enable Bash completion, source {{ic|/usr/share/git/completion/git-completion.bash}} in a [[Bash#Configuration_files|Bash startup file]]. Alternatively, install {{pkg|bash-completion}}.<br />
<br />
=== Git prompt ===<br />
<br />
The Git package comes with a prompt script. To enable it, source the {{ic|/usr/share/git/completion/git-prompt.sh}} script in a [[Autostarting#Shells|shell startup file]], then set a custom prompt with the {{ic|%s}} parameter:<br />
<br />
* For [[Bash]]: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* For [[zsh]]: {{ic|1=PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Shell variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || '''+''' for staged, '''*''' if unstaged. <br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || '''$''' if something is stashed.<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || '''%''' if there are untracked files.<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' behind, ahead, or diverged from upstream.<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} will need to be set to {{ic|auto}} for changes to take effect.<br />
<br />
{{Note|If you experience that {{ic|$(__git_ps1)}} returns {{ic|((unknown))}}, then there is a {{ic|.git}} folder in your current directory which does not contain any repository, and therefore Git does not recognize it. This can, for example, happen if you mistake Git's configuration file to be {{ic|~/.git/config}} instead of {{ic|~/.gitconfig}}.}}<br />
<br />
== Advanced usage ==<br />
<br />
To get an idea of the amount of work done:<br />
<br />
$ git diff --stat<br />
<br />
''git log'' with forking representation:<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
''git log'' graph alias (i.e. ''git graph'' will show a decorated version):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
Reset to previous commit (very dangerous, erases everything to specified commit):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
If a repository address gets changed, its remote location will need to be updated:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):<br />
<br />
$ git commit -s<br />
<br />
Signed-off-by automatically append to patches (when using {{ic|git format-patch ''commit''}}):<br />
<br />
$ git config --local format.signoff true<br />
<br />
Commit specific parts of files that have changed. This is useful if there are a large number of changes made that would be best split into several commits:<br />
<br />
$ git add -p<br />
<br />
=== Working with a non-master branch ===<br />
<br />
Occasionally a maintainer will ask that work be done on a branch. These branches are often called {{ic|devel}} or {{ic|testing}}. Begin by cloning the repository.<br />
<br />
To enter another branch beside master (''git clone'' only shows master branch but others still exist, {{ic|git branch -a}} to show):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
Now edit normally; however to keep the repository tree in sync be sure to use both:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
== Git server ==<br />
<br />
How to set up connecting to repositories using varying protocols.<br />
<br />
=== SSH ===<br />
<br />
To use the SSH protocol, first set up a public SSH key; for that follow the guide at [[SSH keys]]. To set up a SSH server, follow the [[SSH]] guide.<br />
<br />
With SSH working and a key generated, paste the contents of {{ic|~/.ssh/id_rsa.pub}} to {{ic|~/.ssh/authorized_keys}} (be sure it is all on one line). Now the Git repository can be accessed with SSH by doing:<br />
<br />
$ git clone ''user''@''foobar.com'':''my_repository''.git<br />
<br />
You should now get an SSH yes/no question, if you have the SSH client setting {{ic|StrictHostKeyChecking}} set to {{ic|ask}} (the default). Type {{ic|yes}} followed by {{ic|Enter}}. Then you should have your repository checked out. Because this is with SSH, you also have commit rights now.<br />
<br />
To modify an existing repository to use SSH, the remote location will need to be redefined:<br />
<br />
$ git remote set-url origin git@localhost:''my_repository''.git<br />
<br />
Connecting on a port other than 22 can be configured on a per-host basis in {{ic|/etc/ssh/ssh_config}} or {{ic|~/.ssh/config}}. To set up ports for a repository, if the repository is in {{ic|~/}} and using 443 for the port:<br />
<br />
{{hc|~/.git/config|2=<br />
[remote "origin"]<br />
url = ssh://''user''@''foobar''.com:443/~''my_repository''/repo.git<br />
}}<br />
<br />
=== Smart HTTP ===<br />
<br />
Git is able to use the HTTP(S) protocol as efficiently as the SSH or Git protocols, by utilizing the git-http-backend. Furthermore it is not only possible to clone or pull from repositories, but also to push into repositories over HTTP(S).<br />
<br />
The setup for this is rather simple as all you need to have installed is the Apache web server ({{pkg|apache}}, with {{ic|mod_cgi}}, {{ic|mod_alias}}, and {{ic|mod_env}} enabled) and of course, {{pkg|git}}.<br />
<br />
Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at:<br />
<br />
{{hc|/etc/httpd/conf/httpd.conf|<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
}}<br />
<br />
This assumes your Git repositories are located at {{ic|/srv/git}} and that you want to access them via something like: {{ic|<nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>}}.<br />
<br />
{{Note|Make sure that Apache can read and write to your repositories.}}<br />
<br />
For more detailed documentation, visit the following links:<br />
* http://progit.org/2010/03/04/smart-http.html<br />
* https://www.kernel.org/pub/software/scm/git/docs/v1.7.10.1/git-http-backend.html<br />
<br />
=== Git ===<br />
<br />
{{Note|The Git protocol only allows read access.}}<br />
<br />
[[start|Start and enable]] {{ic|git-daemon.socket}}.<br />
<br />
The daemon is started with the following options:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
Repositories placed in {{ic|/srv/git/}} will be recognized by the daemon. Clients can connect with something similar to:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== Setting access rights ===<br />
<br />
To restrict read and/or write access, use standard Unix permissions. Refer to http://sitaramc.github.com/gitolite/doc/overkill.html{{Dead link|2013|11|06}} ([https://web.archive.org/web/20111004134500/http://sitaramc.github.com/gitolite/doc/overkill.html archive.org mirror]) for more information.<br />
<br />
For fine-grained access management, refer to [[gitolite]] and [[gitosis]].<br />
<br />
== See also ==<br />
<br />
* [http://git-scm.com/book Pro Git book]<br />
* [http://gitref.org/ Git Reference]<br />
* https://www.kernel.org/pub/software/scm/git/docs/<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request Git overall]<br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git overall2]<br />
* https://wiki.videolan.org/Git<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols offered by GitHub]</div>Chehrihttps://wiki.archlinux.org/index.php?title=Dnscrypt-proxy&diff=379082Dnscrypt-proxy2015-06-16T19:56:28Z<p>Chehri: The Wiki now already shows if a package is from the AUR or not.</p>
<hr />
<div>[[Category:Domain Name System]]<br />
[[Category:Encryption]]<br />
[[es:DNSCrypt]]<br />
[[pt:DNSCrypt]]<br />
[http://dnscrypt.org/ DNSCrypt] encrypts and authenticates DNS traffic between user and DNS resolver. While IP traffic itself is unchanged, it prevents local spoofing of DNS queries, ensuring DNS responses are sent by the server of choice. [https://www.reddit.com/r/sysadmin/comments/2hn435/dnssec_vs_dnscrypt/ckuhcbu]<br />
<br />
== Installation ==<br />
<br />
[[Install]] {{Pkg|dnscrypt-proxy}}.<br />
<br />
== Configuration ==<br />
<br />
{{Tip|To interactively choose a DNSCrypt resolver, use {{AUR|dnscrypt-autoinstall}}.}}<br />
<br />
By default ''dnscrypt-proxy'' is pre-configured in {{ic|/etc/conf.d/dnscrypt-proxy}} (read by {{ic|dnscrypt-proxy.service}}) to accept incoming requests on {{ic|127.0.0.1}} to an [https://opendns.com OpenDNS] resolver. See the [https://github.com/jedisct1/dnscrypt-proxy/blob/master/dnscrypt-resolvers.csv list of public resolvers] for alternatives.<br />
<br />
With this setup, it will be necessary to alter your [[resolv.conf]] file and replace your current set of resolver addresses with localhost:<br />
nameserver 127.0.0.1<br />
<br />
You might need to prevent other programs from overwriting it, see [[resolv.conf#Preserve DNS settings]] for details.<br />
<br />
== Starting ==<br />
<br />
Available as a [[systemd]] service: {{ic|dnscrypt-proxy.service}}<br />
<br />
== Tips and tricks ==<br />
<br />
=== DNSCrypt as a forwarder for local DNS cache ===<br />
<br />
It is recommended to run DNSCrypt as a forwarder for a local DNS cache, otherwise every single query will make a round-trip to the upstream resolver. Any local DNS caching program should work, examples below show configuration for [[Unbound]], [[dnsmasq]], and [[pdnsd]].<br />
<br />
==== Example: configuration for Unbound ====<br />
<br />
Configure [[Unbound]] to your liking (remember to [[Unbound#Set /etc/resolv.conf to use the local DNS server|set /etc/resolv.conf to use the local DNS server]]) and add the following lines to the end of the {{ic|server}} section in {{ic|/etc/unbound/unbound.conf}}:<br />
do-not-query-localhost: no<br />
forward-zone:<br />
name: "."<br />
forward-addr: 127.0.0.1@40<br />
<br />
{{Note|Port 40 is given as an example as Unbound by default listens to 53, these must be different.}}<br />
<br />
{{Tip|If you are setting up a server add {{ic|interface: 0.0.0.0@53}} and {{ic|access-control: ''your-network''/''subnet-mask'' allow}} inside the {{ic|server:}} section so that the other computers of your LAN can connect to the server. A client must be configured with {{ic|nameserver ''address-of-your-server''}} in {{ic|/etc/resolv.conf}}.}}<br />
<br />
Start the [[systemd]] service {{ic|unbound.service}}. Then configure DNScrypt to match Unbound's new {{ic|forward-zone}} IP and port in {{ic|/etc/conf.d/dnscrypt-proxy}}:<br />
DNSCRYPT_LOCALIP=127.0.0.1<br />
DNSCRYPT_LOCALPORT=40<br />
<br />
{{Note|DNSCrypt needs to start before Unbound, so include {{ic|unbound.service}} on a {{ic|1=Before=}} line in the {{ic|[Unit]}} section of {{ic|dnscrypt-proxy.service}}.}}<br />
<br />
Restart {{ic|dnscrypt-proxy.service}} and {{ic|unbound.service}} to apply the changes.<br />
<br />
==== Example: configuration for dnsmasq ====<br />
<br />
Configure dnsmasq as a [[dnsmasq#DNS Cache Setup|local DNS cache]]. The basic configuration to work with DNSCrypt:<br />
<br />
{{hc|/etc/dnsmasq.conf|2=<br />
no-resolv<br />
server=127.0.0.2#2053<br />
listen-address=127.0.0.1<br />
}}<br />
<br />
If you configured DNSCrypt to use a resolver with enabled DNSSEC validation, make sure to enable it also in dnsmasq:<br />
<br />
{{hc|/etc/dnsmasq.conf|2=<br />
proxy-dnssec<br />
}}<br />
<br />
Configure DNSCrypt to listen on {{ic|127.0.0.2}}, where dnsmasq will be querying:<br />
<br />
{{hc|/etc/conf.d/dnscrypt-proxy|2=<br />
DNSCRYPT_LOCALIP=127.0.0.2<br />
DNSCRYPT_LOCALPORT=2053<br />
}}<br />
<br />
Restart {{ic|dnscrypt-proxy.service}} and {{ic|dnsmasq.service}} to apply the changes.<br />
<br />
==== Example: configuration for pdnsd ====<br />
<br />
Install [[pdnsd]]. A basic configuration to work with DNSCrypt is:<br />
<br />
{{hc|/etc/pdnsd.conf|2=<br />
global {<br />
perm_cache=16384;<br />
cache_dir="/var/cache/pdnsd";<br />
run_as="pdnsd";<br />
server_ip = 127.0.0.1;<br />
status_ctl = on;<br />
query_method=udp_tcp;<br />
min_ttl=15m; # Retain cached entries at least 15 minutes.<br />
max_ttl=1w; # One week.<br />
timeout=10; # Global timeout option (10 seconds).<br />
neg_domain_pol=on;<br />
udpbufsize=1024; # Upper limit on the size of UDP messages.<br />
}<br />
<br />
server {<br />
label = "dnscrypt-proxy";<br />
ip = 127.0.0.2;<br />
port = 53;<br />
timeout = 4;<br />
uptest = query;<br />
interval = 15m;<br />
proxy_only=on;<br />
}<br />
<br />
source {<br />
owner=localhost;<br />
file="/etc/hosts";<br />
}<br />
<br />
<br />
rr {<br />
name=localhost;<br />
reverse=on;<br />
a=127.0.0.1;<br />
owner=localhost;<br />
soa=localhost,root.localhost,42,86400,900,86400,86400;<br />
}<br />
}}<br />
<br />
Configure DNSCrypt to listen on {{ic|127.0.0.2:53}} where pdnsd will be querying. The following has an example provider already in place. Be sure to use the provider you have chosen.<br />
<br />
{{hc|/etc/conf.d/dnscrypt-proxy|2=<br />
DNSCRYPT_LOCALIP=127.0.0.2<br />
DNSCRYPT_LOCALPORT=53<br />
DNSCRYPT_USER=nobody<br />
DNSCRYPT_PROVIDER_NAME=2.dnscrypt-cert.opendns.com<br />
DNSCRYPT_PROVIDER_KEY=B735:1140:206F:225D:3E2B:D822:D7FD:691E:A1C3:3CC8:D666:8D0C:BE04:BFAB:CA43:FB79<br />
DNSCRYPT_RESOLVERIP=208.67.220.220<br />
DNSCRYPT_RESOLVERPORT=443<br />
}}<br />
<br />
Be sure you have [[#Configuration|configured resolv.conf properly]] for {{ic|127.0.0.1}}.<br />
<br />
[[systemd#Editing provided unit files|Edit]] the {{ic|dnscrypt-proxy.service}} and uncomment {{ic|1=Before=pdnsd.service}}. Then [[enable]] both the {{ic|pdnsd}} and {{ic|dnscrypt-proxy}} services.<br />
<br />
=== Enable EDNS0 ===<br />
<br />
[[wikipedia:Extension_mechanisms_for_DNS|Extension Mechanisms for DNS]] that, among other things, allows a client to specify how large a reply over UDP can be.<br />
<br />
Add the following line to your {{ic|/etc/resolv.conf}}:<br />
options edns0<br />
<br />
You may also wish to add the following argument to ''dnscrypt-proxy'':<br />
--edns-payload-size=<bytes><br />
<br />
The default size being '''1252''' bytes, with values up to '''4096''' bytes being purportedly safe. A value below or equal to '''512''' bytes will disable this mechanism, unless a client sends a packet with an OPT section providing a payload size.<br />
<br />
==== Test EDNS0 ====<br />
<br />
Make use of the [https://www.dns-oarc.net/oarc/services/replysizetest DNS Reply Size Test Server], use the ''dig'' command line tool available with {{Pkg|dnsutils}} from the [[official repositories]] to issue a TXT query for the name ''rs.dns-oarc.net'':<br />
$ dig +short rs.dns-oarc.net txt<br />
<br />
With '''EDNS0''' supported, the output should look similar to this:<br />
rst.x3827.rs.dns-oarc.net.<br />
rst.x4049.x3827.rs.dns-oarc.net.<br />
rst.x4055.x4049.x3827.rs.dns-oarc.net.<br />
"2a00:d880:3:1::a6c1:2e89 DNS reply size limit is at least 4055 bytes"<br />
"2a00:d880:3:1::a6c1:2e89 sent EDNS buffer size 4096"</div>Chehrihttps://wiki.archlinux.org/index.php?title=Git&diff=378183Git2015-06-11T22:19:41Z<p>Chehri: Using Git over SSH is a much safer method.</p>
<hr />
<div>[[Category:Version Control System]]<br />
[[zh-CN:Git]]<br />
{{Related articles start}}<br />
{{Related|Super Quick Git Guide}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
<br />
[[wikipedia:Git_%28software%29|Git]] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain sources for the Linux kernel as well as thousands of other projects, including a number of Arch Linux projects. <br />
<br />
== Installation ==<br />
<br />
[[Install]] {{Pkg|git}} from the [[official repositories]].<br />
<br />
If you want to use Git's built-in GUI tools (e.g. ''gitk'' or ''git gui''), make sure you have installed the {{Pkg|tk}} package, or they will refuse to start with a cryptic error:<br />
<br />
/usr/bin/gitk: line 3: exec: wish: not found.<br />
<br />
Also, the GUI tools require {{pkg|gsfonts}}, or they will crash with a segmentation fault.<br />
<br />
If you want to use the Git SVN bridge (''git svn'') you will need {{pkg|perl-term-readkey}}, or you will receive the following error: <br />
<br />
Can't locate Term/ReadKey.pm in @INC (you may need to install the Term::ReadKey module)<br />
<br />
== Basic configuration ==<br />
<br />
In order to use Git you need to set at least a name and email:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@foobar.com''"<br />
<br />
See [[#Advanced configuration]] for more settings.<br />
<br />
== Basic usage ==<br />
<br />
This tutorial teaches how to use Git for basic distributed revision control of a project. A typical Git workflow is generally:<br />
<br />
# Create a new project or clone a remote one.<br />
# Create a branch to make changes; then commit those changes.<br />
# Consolidate commits for better organization/understanding.<br />
# Merge commits back into the main branch.<br />
# (Optional) Push changes to a remote server.<br />
<br />
=== Local repository ===<br />
<br />
==== Create a repository ====<br />
<br />
Initialize a new repository:<br />
<br />
$ git init<br />
<br />
Add files to the repository index:<br />
<br />
$ git add ''file1'' ''file2''<br />
<br />
Or, to add all files:<br />
<br />
$ git add .<br />
<br />
{{Tip|To use ''git add'' and have some files ignored, create a {{ic|.gitignore}} file:<br />
<br />
{{hc|.gitignore|<br />
# File I'll likely delete<br />
test-script<br />
}}<br />
}}<br />
<br />
Remove a file:<br />
<br />
$ git rm ''file''<br />
<br />
Rename a file:<br />
<br />
$ git mv ''file1'' ''file2''<br />
<br />
List files:<br />
<br />
$ git ls-files<br />
<br />
==== Commit changes ====<br />
<br />
In order to record the changes to the repository, they must first be added to the ''index'', or ''staging area'', with an operation often also referred to as ''staging''. This is done with the ''git add'' command:<br />
<br />
$ git add ''file''<br />
<br />
Once the content to be recorded is staged, it can be ''committed'' to the repository:<br />
<br />
$ git commit --message "First commit."<br />
<br />
The {{ic|--message}} option is for a short message: if omitted, the preset editor will be spawned to allow entering a longer message.<br />
<br />
{{Tip|<br />
* Always commit small changes frequently and with meaningful messages.<br />
* If you want to add all the modified files to the index, and commit them in a single command, do:<br />
<br />
$ git commit --all --message "First commit."<br />
}}<br />
<br />
To go back and edit the commit message:<br />
<br />
$ git commit --amend<br />
<br />
Many of the commands in this article take commits as arguments. A commit can be identified by any of the following:<br />
<br />
* Its 40-digit SHA-1 hash (the first 7 digits are usually sufficient to identify it uniquely)<br />
* Any commit label such as a branch or tag name<br />
* The label {{ic|HEAD}} always refers to the currently checked-out commit (usually the head of the branch, unless you used {{ic|git checkout}} to jump back in history to an old commit)<br />
* Any of the above plus {{ic|~}} to refer to previous commits. For example, {{ic|HEAD~}} refers to one commit before {{ic|HEAD}} and {{ic|HEAD~5}} refers to five commits before {{ic|HEAD}}.<br />
<br />
==== View changes ====<br />
<br />
Show differences between commits:<br />
<br />
$ git diff<br />
<br />
To get a general overview of the changes:<br />
<br />
$ git status<br />
<br />
View history of changes with:<br />
<br />
$ git log<br />
<br />
==== Branch a repository ====<br />
<br />
Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch. Branch names should reflect the alteration accurately:<br />
<br />
$ git branch help-section-addition<br />
<br />
To see the created branches:<br />
<br />
$ git branch<br />
<br />
To switch to a branch:<br />
<br />
$ git checkout ''branch''<br />
<br />
To create and switch to a branch in one step:<br />
<br />
$ git checkout -b ''branch''<br />
<br />
To merge a branch back to the master branch:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
The changes will be merged if they do not conflict. If they do, the conflicts will be recorded. What is causing the conflicts can been seen with {{ic|git diff}}, then conflict resolution will need to be done manually.<br />
<br />
When done with a branch, it can be deleted by:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== Collaboration ===<br />
<br />
==== Adopting a good etiquette ====<br />
<br />
* When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.<br />
* Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the [[#History and versioning|log]] of the repository.<br />
* When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.<br />
* If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.<br />
<br />
==== Clone a repository ====<br />
<br />
To begin contributing to a project start by cloning its repository:<br />
<br />
$ git clone ''location'' ''folder''<br />
<br />
{{ic|''location''}} can be either a path or network address. Also, when cloning is done, the location is recorded so just a {{ic|git pull}} will be needed later.<br />
<br />
==== Pull requests ====<br />
<br />
After making and committing some changes, the contributor can ask the original author to the merge them; this is called a "pull request".<br />
<br />
The original author can merge the changes by doing:<br />
<br />
$ git pull ''location'' master<br />
<br />
The ''pull'' command fetches the changes and attempts to merge them. If there are conflicts (e.g. the original author made changes in the same time span) then it will be necessary to manually fix them.<br />
<br />
Alternatively, the original author can pick the changes wanting to be incorporated. Using the fetch option (and log option with a special {{ic|FETCH_HEAD}} symbol) the contents of the pull request can be viewed before deciding what to do:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== Using remotes ====<br />
<br />
Remotes are tracked repositories, a {{ic|''label''}} defining a location. They are commonly used for frequently accessed repositories.<br />
<br />
$ git remote add ''label'' ''location''<br />
$ git fetch ''label''<br />
$ git log -p master..''label''/master<br />
<br />
Remotes for the current repository can be viewed with:<br />
<br />
$ git remote -v<br />
<br />
When defining a remote that is a parent of the fork (the project lead), it is defined as ''upstream''.<br />
<br />
==== Push to a repository ====<br />
<br />
If the contributor is given the rights from the original authors, the changes can be pushed:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
When {{ic|git clone}} is performed it records the original location and gives it a remote name of {{ic|origin}}. So what is typically done is this:<br />
<br />
$ git push origin master<br />
<br />
If the {{ic|--set-upstream}} option is used, the location is recorded so the next time just a {{ic|git push}} is necessary.<br />
<br />
==== Dealing with merges ====<br />
<br />
See [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts Basic Merge Conflicts] in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the {{ic|--abort}} command (e.g. {{ic|git merge --abort}} or {{ic|git pull --abort}}).<br />
<br />
==== Send patch to mailing list ====<br />
If you want to send patches directly to a mailing list you have to install the following packages: {{Pkg|perl-authen-sasl}}, {{Pkg|perl-net-smtp-ssl}} and {{Pkg|perl-mime-tools}}.<br />
<br />
Make sure you have configured you username and e-mail address: [[Git#Basic_configuration|Basic configuration]].<br />
<br />
Configure your e-mail settings:<br />
git config --global sendemail.smtpserver smtp.gmail.com<br />
git config --global sendemail.smtpserverport 587<br />
git config --global sendemail.smtpencryption tls<br />
git config --global sendemail.smtpuser tekkupl@gmail.com<br />
<br />
Now you should be able to send the patch to the mailing list (see also [http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches Sending patches]):<br />
git add <filename><br />
git commit -s # don't use the -m option but include my signature<br />
git send-email --to=openembedded-core@lists.openembedded.org --confirm=always -M -1<br />
<br />
=== History and versioning ===<br />
<br />
==== Searching the history ====<br />
<br />
{{ic|git log}} will give the history with a commit checksum, author, date, and the short message. To see the long message (the checksum can be truncated as long as it is unique):<br />
<br />
$ git show ''checksum''<br />
<br />
To show details of the last commit:<br />
<br />
$ git show HEAD<br />
<br />
To search through files of a previous commit it can be done with:<br />
<br />
$ git grep ''checksum''<br />
<br />
Ranges can also be specified:<br />
<br />
$ git grep ''tag2''..''tag4''<br />
<br />
==== Versioning for release ====<br />
<br />
For versioning, commits can be tagged:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
Tagging is generally done for [https://www.drupal.org/node/1066342 releasing/versioning] but it can be any string. Generally annotated tags are used because they get added to the Git database. To tag the current commit:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
Tags can be listed and deleted with:<br />
<br />
$ git tag -l<br />
$ git tag -d 2.08<br />
<br />
Tags that have to be updated remotely, have to be done so separately:<br />
<br />
$ git push --tags<br />
<br />
==== Organizing commits ====<br />
<br />
Before submitting a pull request it may be desirable to consolidate/organize the commits. This is done with the {{ic|git rebase}} interactive option:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
This will open the editor with a summary of all the commits in the range specified; in this case including the newest ({{ic|HEAD}}) to, but excluding, {{ic|''checksum''}}. Or to use a number notation, use for example {{ic|HEAD~3}}, which will rebase the last three commits.<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
Editing the action in the first column will dictate how the rebase will be done. The options are:<br />
<br />
* {{ic|pick}} — Apply this commit as is (the default).<br />
* {{ic|edit}} — Edit files and/or commit message.<br />
* {{ic|reword}} — Edit commit message.<br />
* {{ic|squash}} — Merge/fold into previous commit.<br />
* {{ic|fixup}} — Merge/fold into previous commit discarding its message.<br />
<br />
The commits can be re-ordered or erased from the history (but be very careful with these). After editing the file, Git will perform the specified actions; if prompted to resolve merge problems, fix them and continue with {{ic|git rebase --continue}} or back out with the {{ic|git rebase --abort}} command.<br />
<br />
{{Note|Squashing commits is only used for local commits, it will cause troubles on a repository that is shared by other people.}}<br />
<br />
== Advanced configuration ==<br />
<br />
Git reads its configuration from a few INI-type configuration files:<br />
<br />
* Each repository contains a {{ic|.git/config}} file for specific configuration.<br />
* Each user has a {{ic|$HOME/.gitconfig}} file for fallback values.<br />
* {{ic|/etc/gitconfig}} is used for system-wide defaults.<br />
<br />
These files can be edited directly, but the usual method is to use the ''git-config'' utility as shown in the examples below.<br />
<br />
To list the currently set variables:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
The default editor is [[vim]] but to set it to [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
To set a default push action:<br />
<br />
$ git config --global push.default simple<br />
<br />
To set a tool for ''git difftool'' (by default it is ''meld''):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
See [https://www.kernel.org/pub/software/scm/git/docs/git-config.html git-config(1)] and [http://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration] for more information.<br />
<br />
=== Speeding up SSH ===<br />
<br />
Often if you find yourself pushing constantly to a few common servers, you may wish to remove the hassle of setting your username for each repository. <br />
<br />
If you do not already have the keys created, make them now.<br />
<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/aur -C "user@domain.com"<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/github -C "user@domain.com"<br />
<br />
Add the resulting public keys to your accounts.<br />
<br />
Additionally, reusing the same SSH connection will drastically improve the time {{ic|git push}} takes.<br />
<br />
$ mkdir -p ~/.ssh/sockets/<br />
<br />
You may wish to adjust the {{ic|ServerAliveInterval}} depending on your connection.<br />
<br />
{{hc|~/.ssh/config|<br />
Host *<br />
ControlMaster auto<br />
ControlPath ~/.ssh/sockets/%r@%h-%p<br />
ControlPersist 8760h<br />
ServerAliveInterval 5<br />
ServerAliveCountMax 1<br />
TCPKeepAlive yes<br />
<br />
Host aur-dev.archlinux.org<br />
IdentityFile ~/.ssh/aur<br />
User aur<br />
Port 2222<br />
<br />
Host github.com<br />
IdentityFile ~/.ssh/github<br />
User [username here]<br />
}}<br />
<br />
=== Protocol Defaults ===<br />
<br />
If you are running a multiplexed SSH connection as shown above, Git over SSH might be faster than HTTPS. Also, you will not have to enter your password on every push until your multiplexed connection goes down (and only if there is a passphrase on it). For example, the following config will set Git over SSH for any repository hosted on GitHub.<br />
<br />
{{hc|~/.gitconfig|<br />
[url "ssh://git@github.com/"]<br />
insteadOf &#61; https://github.com/<br />
insteadOf &#61; http://github.com/<br />
insteadOf &#61; git://github.com/<br />
}}<br />
<br />
Optionally, the Git protocol could be used for pulling instead. <br />
<br />
{{Warning|There is absolutely no encryption or verification with the server using the Git protocol by itself. Please be careful with software after obtaining through this method.}}<br />
<br />
{{hc|~/.gitconfig|<br />
[url "ssh://git@github.com/"]<br />
pushInsteadOf &#61; https://github.com/<br />
[url "git://github.com/"]<br />
insteadOf &#61; https://github.com/<br />
insteadOf &#61; http://github.com/<br />
}}<br />
<br />
{{Note|Some corporate firewalls block port 9418/TCP, which the Git protocol uses. In those situations, Git over SSH or HTTPS will likely be the best option.}}<br />
<br />
=== Bash completion ===<br />
<br />
In order to enable Bash completion, source {{ic|/usr/share/git/completion/git-completion.bash}} in a [[Bash#Configuration_files|Bash startup file]]. Alternatively, install {{pkg|bash-completion}}.<br />
<br />
=== Git prompt ===<br />
<br />
The Git package comes with a prompt script. To enable it, source the {{ic|/usr/share/git/completion/git-prompt.sh}} script in a [[Autostarting#Shells|shell startup file]], then set a custom prompt with the {{ic|%s}} parameter:<br />
<br />
* For [[Bash]]: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* For [[zsh]]: {{ic|1=PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Shell variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || '''+''' for staged, '''*''' if unstaged. <br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || '''$''' if something is stashed.<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || '''%''' if there are untracked files.<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' behind, ahead, or diverged from upstream.<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} will need to be set to {{ic|auto}} for changes to take effect.<br />
<br />
{{Note|If you experience that {{ic|$(__git_ps1)}} returns {{ic|((unknown))}}, then there is a {{ic|.git}} folder in your current directory which does not contain any repository, and therefore Git does not recognize it. This can, for example, happen if you mistake Git's configuration file to be {{ic|~/.git/config}} instead of {{ic|~/.gitconfig}}.}}<br />
<br />
== Advanced usage ==<br />
<br />
To view get an idea of the amount of work done:<br />
<br />
$ git diff --stat<br />
<br />
Git log with forking representation:<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
Git log graph alias (i.e. {{ic|git graph}} will show the previous):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
Reset to previous commit (very dangerous, erases everything to specified commit):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
If a repository address gets changed, its remote location will need to be updated:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):<br />
<br />
$ git commit -s<br />
<br />
Signed-off-by automatically append to patches (when using {{ic|git format-patch ''commit''}}):<br />
<br />
$ git config --local format.signoff true<br />
<br />
Commit specific parts of files that have changed. This is useful if there are a large number of changes made that would be best split into several commits:<br />
<br />
$ git add -p<br />
<br />
=== Working with a non-master branch ===<br />
<br />
Occasionally a maintainer will ask that work be done on a branch. These branches are often called {{ic|devel}} or {{ic|testing}}. Begin by cloning the repository.<br />
<br />
To enter another branch beside master ({{ic|git clone}} only shows master branch but others still exist, {{ic|git branch -a}} to show):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
Now edit normally; however to keep the repository tree in sync be sure to use both:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
== Git server ==<br />
<br />
How to set up connecting to repositories using varying protocols.<br />
<br />
=== SSH ===<br />
<br />
To use the SSH protocol, first set up a public SSH key; for that follow the guide at [[SSH keys]]. To set up a SSH server, follow the [[SSH]] guide.<br />
<br />
With SSH working and a key generated, paste the contents of {{ic|~/.ssh/id_rsa.pub}} to {{ic|~/.ssh/authorized_keys}} (be sure it is all on one line). Now the Git repository can be accessed with SSH by doing:<br />
<br />
$ git clone user@foobar.com:repository-name.git<br />
<br />
You should now get an SSH yes/no question, if you have the SSH client setting {{ic|StrictHostKeyChecking}} set to {{ic|ask}} (the default). Type {{ic|yes}} followed by {{ic|Enter}}. Then you should have your repository checked out. Because this is with SSH, you also have commit rights now.<br />
<br />
To modify an existing repository to use SSH, the remote location will need to be redefined:<br />
<br />
$ git remote set-url origin git@localhost:my_repository.git<br />
<br />
Connecting on a port other than 22 can be configured on a per-host basis in {{ic|/etc/ssh/ssh_config}} or {{ic|~/.ssh/config}}. To set up ports for a repository, specify the path in {{ic|.git/config}}. It will have a format like this if the repository is in the home directory and is using 443 for the port:<br />
<br />
<nowiki>url = ssh://user@foobar.com:443/~repository-name/repo.git</nowiki><br />
<br />
=== Smart HTTP ===<br />
<br />
Git is able to use the HTTP(S) protocol as efficiently as the SSH or Git protocols, by utilizing the git-http-backend. Furthermore it is not only possible to clone or pull from repositories, but also to push into repositories over HTTP(S).<br />
<br />
The setup for this is rather simple as all you need to have installed is the Apache web server ({{pkg|apache}}, with {{ic|mod_cgi}}, {{ic|mod_alias}}, and {{ic|mod_env}} enabled) and of course, {{pkg|git}}.<br />
<br />
Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at {{ic|/etc/httpd/conf/httpd.conf}}:<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
<br />
The above example configuration assumes that your Git repositories are located at {{ic|/srv/git}} and that you want to access them via something like <nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>. Feel free to customize this to your needs.<br />
<br />
{{Note|Of course, you have to make sure that Apache can read and write (if you want to enable push access) to your Git repositories.}}<br />
<br />
For more detailed documentation, visit the following links:<br />
* http://progit.org/2010/03/04/smart-http.html<br />
* https://www.kernel.org/pub/software/scm/git/docs/v1.7.10.1/git-http-backend.html<br />
<br />
=== Git ===<br />
<br />
{{Note|The Git protocol only allows read access.}}<br />
<br />
[[start|Start and enable]] {{ic|git-daemon.socket}}.<br />
<br />
The daemon is started with the following options:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
Repositories placed in {{ic|/srv/git/}} will be recognized by the daemon. Clients can connect with something similar to:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== Setting access rights ===<br />
<br />
To restrict read and/or write access, use standard Unix permissions. Refer to http://sitaramc.github.com/gitolite/doc/overkill.html{{Dead link|2013|11|06}} ([https://web.archive.org/web/20111004134500/http://sitaramc.github.com/gitolite/doc/overkill.html archive.org mirror]) for more information.<br />
<br />
For fine-grained access management, refer to [[gitolite]] and [[gitosis]].<br />
<br />
== See also ==<br />
<br />
* [http://git-scm.com/book Pro Git book]<br />
* [http://gitref.org/ Git Reference]<br />
* https://www.kernel.org/pub/software/scm/git/docs/<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request Git overall]<br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git overall2]<br />
* https://wiki.videolan.org/Git<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols offered by GitHub]</div>Chehrihttps://wiki.archlinux.org/index.php?title=GnuPG&diff=370122GnuPG2015-04-19T05:55:28Z<p>Chehri: Added information on subkeys.</p>
<hr />
<div>[[Category:Security]]<br />
[[es:GnuPG]]<br />
[[ja:GnuPG]]<br />
[[ru:GnuPG]]<br />
[http://www.gnupg.org GnuPG] allows to encrypt and sign your data and communication, features a versatile key management system as well as access modules for all kinds of public key directories.<br />
<br />
== Installation ==<br />
<br />
[[Install]] {{Pkg|gnupg}}, available in the [[official repositories]].<br />
<br />
This will also install {{Pkg|pinentry}}, a collection of simple PIN or passphrase entry dialogs which GnuPG uses for passphrase entry. ''pinentry'' is determined by the symbolic link {{ic|/usr/bin/pinentry}}, which by default points to {{ic|/usr/bin/pinentry-gtk-2}}.<br />
<br />
== Environment variables ==<br />
<br />
=== GNUPGHOME ===<br />
<br />
{{ic|$GNUPGHOME}} is used by GnuPG to point to the directory where all configuration files are stored. By default {{ic|$GNUPGHOME}} isn't set and your {{ic|$HOME}} is used instead, thus you will find a {{ic|~/.gnupg}} directory right after the install. You may change this default setting by putting this line in one of your regular [[startup files]]:<br />
<br />
export GNUPGHOME="''/path/to/directory''"<br />
<br />
{{Note|By default, the gnupg directory has its [[Permissions]] set to ''700'' and the files it contains have their permissions set to ''600''. Only the owner of the directory has permission to read, write and access the files (''r'',''w'',''x''). This is for security purposes and should not be changed. In case this directory or any file inside it does not follow this security measure, you will get warnings about unsafe file and home directory permissions.}}<br />
<br />
=== GPG_AGENT_INFO ===<br />
<br />
{{ic|GPG_AGENT_INFO}} used to locate the gpg-agent. Consists of 3 colon delimited fields:<br />
<br />
# path to Unix Domain Socket<br />
# PID of gpg-agent<br />
# protocol version set to 1<br />
<br />
E.g : {{ic|1=GPG_AGENT_INFO=/tmp/gpg-eFqmSC/S.gpg-agent:7795:1}}. When starting the gpg-agent, this variable is set to the correct value.<br />
<br />
{{Note|According to the [https://www.gnupg.org/faq/whats-new-in-2.1.html GnuPG 2.1 announcement]: With GnuPG 2.1 the need of {{ic|GPG_AGENT_INFO}} has been completely removed and the variable is ignored. Instead, a Unix domain socket with fixed name {{ic|$GNUPGHOME/S.gpg-agent}} is used. The agent is also started on demand by all tools requiring services from the agent.}}<br />
<br />
== Configuration file ==<br />
<br />
Default is {{ic|~/.gnupg/gpg.conf}}. If you want to change the default location, either run gpg this way {{ic|$ gpg --homedir ''path/to/file''}} or use {{ic|$GNUPGHOME}} variable.<br />
<br />
Append in this file any long options you want. Do not write the two dashes, but simply the name of the option and required arguments. You will find a skeleton file {{ic|/usr/share/gnupg/gpg-conf.skel}}.<br />
Following is a basic configuration file:<br />
{{hc|~/.gnupg/gpg.conf|<br />
default-key ''name'' # useful in case you manage several keys and want to set a default one<br />
keyring ''file'' # will add ''file'' to the current list of keyrings<br />
trustdb-name ''file'' # use ''file'' instead of the default trustdb<br />
homedir ''dir'' # set the name of the gnupg home dir to ''dir'' instead of ~/.gnupg<br />
display-charset utf-8 # bypass all translation and assume that the OS uses native UTF-8 encoding<br />
keyserver ''name'' # use ''name'' as your keyserver<br />
no-greeting # suppress the initial copyright message<br />
armor # create ASCII armored output. Default is binary OpenPGP format<br />
}}<br />
<br />
If you want to setup some default options for new users, put configuration files in {{ic|/etc/skel/.gnupg/}}. When the new user is added in system, files from here will be copied to its GnuPG home directory. There is also a simple script called ''addgnupghome'' which you can use to create new GnuPG home directories for existing users:<br />
<br />
# addgnupghome user1 user2<br />
<br />
This will add the respective {{ic|/home/user1/.gnupg}} and {{ic|/home/user2/.gnupg}} and copy the files from the skeleton directory to it. Users with existing GnuPG home directory are simply skipped.<br />
<br />
== Basic keys management ==<br />
<br />
{{Note|Whenever a ''{{ic|<user-id>}}'' is required in a command, it can be specified with your key ID, fingerprint, a part of your name or email address, etc. GnuPG is flexible on this.}}<br />
<br />
=== Create key ===<br />
<br />
Set stronger algorithms to be used first:<br />
<br />
{{hc|~/.gnupg/gpg.conf|<br />
personal-digest-preferences SHA512<br />
cert-digest-algo SHA512<br />
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed<br />
personal-cipher-preferences TWOFISH CAMELLIA256 AES 3DES<br />
}}<br />
<br />
Generate a private key by typing in a terminal:<br />
<br />
$ gpg --full-gen-key<br />
<br />
{{Note|The {{ic|--full-gen-key}} option is available since {{Pkg|gnupg}}-2.1.0.}}<br />
<br />
You will be asked several questions. In general, most users will want both a RSA (sign only) and a RSA (encrypt only) key. A keysize of 2048 is sufficient. Using 4096 [https://www.gnupg.org/faq/gnupg-faq.html#no_default_of_rsa4096 "gives us almost nothing, while costing us quite a lot."]<br />
<br />
While having an expiration date for subkeys isn't technically necessary, it is considered good practice. A period of a year is generally good enough for the average user. This way even if you lose access to your keyring, it will allow others to know that it is no longer valid. Note that you can extend the expiry date after key creation without having to re-issue a new key.<br />
<br />
=== Manage your key ===<br />
<br />
* Running the {{ic|gpg --edit-key ''<user-id>''}} command will present a menu which enables you to do most of your key management related tasks. Following is an example to set your expiration date:<br />
<br />
$ gpg --edit-key ''<user-id>''<br />
> key ''number''<br />
> expire ''yyyy-mm-dd''<br />
> save<br />
> quit<br />
<br />
Some useful commands:<br />
> passwd # change the passphrase<br />
> clean # compact any user ID that is no longer usable (e.g revoked or expired)<br />
> revkey # revoke a key<br />
> addkey # add a subkey to this key<br />
> expire # change the key expiration time<br />
<br />
* Generate an ASCII version of your public key (e.g. to distribute it by e-mail):<br />
<br />
$ gpg --armor --output public.key --export ''<user-id>''<br />
<br />
* Register your key with a public PGP key server, so that others can retrieve your key without having to contact you directly:<br />
<br />
$ gpg --keyserver pgp.mit.edu --send-keys ''<key-id>''<br />
<br />
* Sign and encrypt for user Bob<br />
<br />
$ gpg -se -r Bob ''file''<br />
<br />
* make a clear text signature<br />
<br />
$ gpg --clearsign ''file''<br />
<br />
=== Exporting subkey ===<br />
<br />
If you plan to use the same key across multiple devices, you may want to strip out your master key and only keep the bare minimum encryption subkey on less secure systems.<br />
<br />
First, find out which subkey you want to export.<br />
<br />
$ gpg -K<br />
<br />
Select only that subkey to export.<br />
<br />
$ gpg -a --export-secret-subkeys [subkey id]! > /tmp/subkey.gpg<br />
<br />
{{Warning|If you forget to add the !, all of your subkeys will be exported.}}<br />
<br />
At this point you could stop, but it's most likely a good idea to change the passphrase as well. Import the key into a temporary folder. <br />
<br />
$ gpg --homedir /tmp/gpg --import /tmp/subkey.gpg<br />
$ gpg --homedir /tmp/gpg --edit-key ''<user-id>''<br />
> passwd<br />
> save<br />
$ gpg --homedir /tmp/gpg -a --export-secret-subkeys [subkey id]! > /tmp/subkey.altpass.gpg<br />
<br />
{{Note|You will get a warning that the master key wasn't available and the password was not changed, but that can safely be ignored as the subkey password was.}}<br />
<br />
At this point, you can now use {{ic|/tmp/subkey.altpass.gpg}} on your other devices. <br />
<br />
=== Rotating subkeys ===<br />
<br />
{{Warning|'''Never''' delete your expired or revoked subkeys unless you have a good reason. Doing so will cause you to lose the ability to decrypt files encrypted with the old subkey. Please '''only''' delete expired or revoked keys from other users to clean your keyring.}}<br />
<br />
If you have set your subkeys to expire after a set time, you can create new ones. Do this a few weeks in advance to allow others to update their keyring.<br />
<br />
{{Note|You do not need to create a new key simply because it is expired. You can extend the expiration date.}}<br />
<br />
* Create new subkey (repeat for both signing and encrypting key)<br />
<br />
$ gpg --edit-key ''<user-id>''<br />
> addkey<br />
<br />
And answer the following questions it asks (see previous section for suggested settings).<br />
<br />
* Save changes<br />
<br />
> save<br />
<br />
* Update it to a keyserver.<br />
<br />
$ gpg --keyserver pgp.mit.edu --send-keys ''<user-id>''<br />
<br />
{{Note|Revoking expired subkeys is unnecessary and arguably bad form. If you are constantly revoking keys, it may cause others to lack confidence in you.}}<br />
<br />
=== Import key ===<br />
<br />
* Import a public key to your public key ring:<br />
<br />
$ gpg --import public.key<br />
<br />
* Import a private key to your secret key ring:<br />
<br />
$ gpg --import private.key<br />
<br />
* Import key from a key server (if '--keyserver' is omitted, the default is used):<br />
<br />
$ gpg --keyserver pgp.mit.edu --recv-keys <keyid><br />
<br />
=== List keys ===<br />
<br />
* Keys in your public key ring:<br />
<br />
$ gpg --list-keys<br />
<br />
* Keys in your secret key ring:<br />
<br />
$ gpg --list-secret-keys<br />
<br />
== Encrypt and decrypt ==<br />
<br />
When encrypting or decrypting it is possible to have more than one private key in use. If this occurs you need to select the active key. This can be done by using the option {{ic|-u ''<user-id>''}} or by using the option {{ic|--local-user ''<user-id>''}}. This causes the default key to use to be replaced by wanted key.<br />
<br />
To encrypt a file, use:<br />
<br />
$ gpg --encrypt -o secret.tar.gpg secret.tar<br />
<br />
* If you want to change recipient this can be done by the option {{ic|-r ''<user-id>''}} (or {{ic|--recipient ''<user-id>''}}).<br />
* You can use gnupg to encrypt your sensitive documents, but only individual files at a time. If you want to encrypt directories or a whole file-system you should consider using [[TrueCrypt]] or [[EncFS]], though you can always tarball various files and then encrypt them.<br />
<br />
To decrypt a file, use:<br />
<br />
$ gpg --decrypt secret.tar.gpg<br />
<br />
You'll be prompted to enter your passphrase.<br />
<br />
=== Encrypt a password ===<br />
<br />
It can be useful to encrypt some password, so it will not be written in clear on a configuration file. A good example is your email password.<br />
<br />
First create a file with your password. You '''need''' to leave '''one''' empty line after the password, otherwise gpg will return an error message when evaluating the file.<br />
<br />
Then run:<br />
<br />
$ gpg -e -a -r ''<user-id>'' ''your_password_file''<br />
<br />
{{ic|-e}} is for encrypt, {{ic|-a}} for armor (ASCII output), {{ic|-r}} for recipient user ID.<br />
<br />
You will be left with a new {{ic|''your_password_file''.asc}} file.<br />
<br />
== gpg-agent ==<br />
<br />
{{Out of date|[[#GPG_AGENT_INFO]] is deprecated since {{pkg|gnupg}}-2.1. See [[#Unattended passphrase]] for new method.}}<br />
<br />
''gpg-agent'' is mostly used as daemon to request and cache the password for the keychain. This is useful if GnuPG is used from an external program like a mail client. It can be activated by adding following line in {{ic|gpg.conf}}:<br />
<br />
{{hc|~/.gnupg/gpg.conf|use-agent}}<br />
<br />
This tells GnuPG to use the agent whenever it needs the password. However, the agent needs to be already running. To autostart it, add the following entry to your {{ic|.xinitrc}} or {{ic|.bash_profile}}. Remember to change the envfile path if you changed your {{ic|$GNUPGHOME}}.<br />
<br />
{{hc|~/.bash_profile|2=<nowiki><br />
envfile="$HOME/.gnupg/gpg-agent.env"<br />
if [[ -e "$envfile" ]] && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then<br />
eval "$(cat "$envfile")"<br />
else<br />
eval "$(gpg-agent --daemon --enable-ssh-support --write-env-file "$envfile")"<br />
fi<br />
export GPG_AGENT_INFO # the env file does not contain the export statement<br />
export SSH_AUTH_SOCK # enable gpg-agent for ssh<br />
</nowiki>}}<br />
<br />
Log out of the session and log back in. Check if ''gpg-agent'' is activated:<br />
<br />
$ pgrep gpg-agent<br />
<br />
=== Configuration ===<br />
<br />
gpg-agent can be configured via {{ic|~/.gnupg/gpg-agent.conf}} file. The configuration options are listed in {{ic|man gpg-agent}}. For example you can change cache ttl for unused keys:<br />
<br />
{{hc|~/.gnupg/gpg-agent.conf|<br />
default-cache-ttl 3600<br />
}}<br />
<br />
{{Tip|To cache your passphrase for the whole session, please run the following command:<br />
$ /usr/lib/gnupg/gpg-preset-passphrase --preset XXXXXX<br />
<br />
where XXXX is the keygrip. You can get its value when running {{ic|gpg --with-keygrip -K}}. Passphrase will be stored until {{ic|gpg-agent}} is restarted. If you set up {{ic|default-cache-ttl}} value, it will take precedence.<br />
}}<br />
<br />
=== Reload the agent ===<br />
<br />
After changing the configuration, reload the agent by piping the {{ic|RELOADAGENT}} string to {{ic|gpg-connect-agent}}.<br />
<br />
$ echo RELOADAGENT | gpg-connect-agent<br />
<br />
The shell should print {{ic|OK}}.<br />
<br />
=== pinentry ===<br />
<br />
Finally, the agent needs to know how to ask the user for the password. This can be set in the gpg-agent configuration file.<br />
<br />
The default uses a gtk dialog. There are other options - see {{ic|info pinentry}}. To change the dialog implementation set {{ic|pinentry-program}} configuration option:<br />
{{hc|~/.gnupg/gpg-agent.conf|<br />
<br />
# PIN entry program<br />
# pinentry-program /usr/bin/pinentry-curses<br />
# pinentry-program /usr/bin/pinentry-qt4<br />
# pinentry-program /usr/bin/pinentry-kwallet<br />
<br />
pinentry-program /usr/bin/pinentry-gtk-2<br />
}}<br />
<br />
{{Tip|For using {{ic|/usr/bin/pinentry-kwallet}} you have to install the {{Pkg|kwalletcli}} package.}}<br />
<br />
After making this change, reload the gpg-agent.<br />
<br />
=== Start gpg-agent with systemd user ===<br />
<br />
It is possible to use the [[Systemd/User]] facilities to start the agent.<br />
<br />
Create a systemd unit file:<br />
<br />
{{hc|~/.config/systemd/user/gpg-agent.service|2=<br />
[Unit]<br />
Description=GnuPG private key agent<br />
IgnoreOnIsolate=true<br />
<br />
[Service]<br />
Type=forking<br />
ExecStart=/usr/bin/gpg-agent --daemon --homedir=%h/.config/gnupg <br />
ExecStop=/usr/bin/pkill gpg-agent<br />
Restart=on-abort<br />
<br />
[Install]<br />
WantedBy=''MyTarget''.target<br />
}}<br />
<br />
{{Note|<br />
* You may need to set some environment variables for the service, for example {{ic|GNUPGHOME}}. See [[systemd/User#Environment variables]] for details.<br />
* if your gnupg home directory is ~/.gnupg, there is no need to specify its path<br />
* {{ic|gpg -agent}} will not use standard socket, but rather listen for a socket name {{ic|S.gpg-agent}} located in your gnupg home directory. We can thus forget any script to read an environment file and get the path of the random socket created in {{ic|/tmp}}.<br />
}}<br />
<br />
{{Tip|<br />
To ensure your gpg-agent is running and listening to connection, simply run this command: {{ic|$ gpg-connect-agent}}. If your settings are valid, you will be on a prompt (enter ''bye'' and ''quit'' to close connection and leave)<br />
}}<br />
<br />
=== Unattended passphrase ===<br />
<br />
Starting with GnuPG 2.1.0 the use of gpg-agent and pinentry is required; this may break backwards compatibility for passphrases piped in from STDIN using the {{ic|--passphrase-fd 0}} commandline option. In order to have the same type of functionality as the older releases two things must be done:<br />
<br />
First, edit the gpg-agent configuration to allow ''loopback'' pinentry mode:<br />
<br />
{{hc|1=~/.gnupg/gpg-agent.conf|2=<br />
allow-loopback-pinentry<br />
}}<br />
<br />
Restart the gpg-agent process if it's running to let the change take effect.<br />
<br />
Second, either the application needs to be updated to include a commandline parameter to use loopback mode like so:<br />
<br />
$ gpg --pinentry-mode loopback ...<br />
<br />
...or if this is not possible, add the option to the configuration:<br />
<br />
{{hc|1=~/.gnupg/gpg.conf|2=<br />
pinentry-mode loopback<br />
}}<br />
<br />
{{Note|The upstream author indicates setting '''pinentry-mode loopback''' in ''gpg.conf'' may break other usage, using the commandline option should be preferred if at all possible. [https://bugs.g10code.com/gnupg/issue1772] }}<br />
<br />
== Keysigning parties ==<br />
<br />
To allow users to validate keys on the keyservers and in their keyrings (i.e. make sure they are from whom they claim to be), PGP/GPG uses a so-called "Web of Trust". There are many hacker events targeted to maintain this Web of Trust are held, including keysigning parties.<br />
<br />
The [[Wikipedia:Zimmermann–Sassaman key-signing protocol|Zimmermann-Sassaman]] key-signing protocol is a way of making these very effective. [http://www.cryptnet.net/fdp/crypto/keysigning_party/en/keysigning_party.html Here] you'll find a how-to article.<br />
<br />
=== caff ===<br />
<br />
For an easier process of signing keys and sending signatures to the owners after a keysigning party, you can use the tool ''caff''. It can be installed from the AUR with the package {{AUR|caff-svn}} or bundled together with other useful tools in the package {{AUR|signing-party-svn}}.<br />
Either way, there will be a lot of dependencies installing from the AUR. Alternatively you can install them from CPAN with<br />
cpanm Any::Moose<br />
cpanm GnuPG::Interface<br />
<br />
To send the signatures to their owners you need a working [[Wikipedia:Message transfer agent|MTA]]. If you don't have already one, install [[msmtp]].<br />
<br />
== Smartcards ==<br />
<br />
{{Note|{{Pkg|pcsclite}} and {{Pkg|libusb-compat}} have to be installed, and the contained [[systemd#Using units|systemd]] service {{ic|pcscd.service}} has to be running.}}<br />
<br />
GnuPG uses ''scdaemon'' as an interface to your smartcard reader, please refer to the [[man page]] for details.<br />
<br />
=== GnuPG only setups ===<br />
<br />
If you do not plan to use other cards but those based on GnuPG, you should check the {{Ic|reader-port}} parameter in {{ic|~/.gnupg/scdaemon.conf}}. The value '0' refers to the first available serial port reader and a value of '32768' (default) refers to the first USB reader.<br />
<br />
=== GnuPG together with OpenSC ===<br />
<br />
If you are using any smartcard with an opensc driver (e.g.: ID cards from some countries) you should pay some attention to GnuPG configuration. Out of the box you might receive a message like this when using {{Ic|gpg --card-status}}<br />
<br />
gpg: selecting openpgp failed: ec=6.108<br />
<br />
By default, scdaemon will try to connect directly to the device. This connection will fail if the reader is being used by another process. For example: the pcscd daemon used by OpenSC. To cope with this situation we should use the same underlying driver as opensc so they can work well together. In order to point scdaemon to use pcscd you should remove {{Ic|reader-port}} from {{ic|~/.gnupg/scdaemon.conf}}, specify the location to {{ic|libpcsclite.so}} library and disable ccid so we make sure that we use pcscd:<br />
<br />
{{hc|~/.gnupg/scdaemon.conf|<nowiki><br />
pcsc-driver /usr/lib/libpcsclite.so<br />
card-timeout 5<br />
disable-ccid<br />
</nowiki>}}<br />
<br />
Please check {{Ic|man scdaemon}} if you do not use OpenSC.<br />
<br />
== Troubleshooting ==<br />
<br />
=== Not enough random bytes available ===<br />
When generating a key, gpg can run into this error:<br />
Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy!<br />
To check the available entropy, check the kernel parameters:<br />
cat /proc/sys/kernel/random/entropy_avail<br />
A healthy Linux system with a lot of entropy available will have return close to the full 4,096 bits of entropy. If the value returned is less than 200, the system is running low on entropy. <br />
<br />
To solve it, remember you do not often need to create keys and best just do what the message suggests (e.g. create disk activity, move the mouse, edit the wiki - all will create entropy). If that does not help, check which service is using up the entropy and consider stopping it for the time. If that is no alternative, see [[Random number generation#Faster alternatives]].<br />
<br />
=== su ===<br />
<br />
When using {{Ic|pinentry}}, you must have the proper permissions of the terminal device (e.g. {{Ic|/dev/tty1}}) in use. However, with ''su'' (or ''sudo''), the ownership stays with the original user, not the new one. This means that pinentry will fail, even as root. The fix is to change the permissions of the device at some point before the use of pinentry (i.e. using gpg with an agent). If doing gpg as root, simply change the ownership to root right before using gpg:<br />
<br />
chown root /dev/ttyN # where N is the current tty<br />
<br />
and then change it back after using gpg the first time. The equivalent is likely to be true with {{Ic|/dev/pts/}}.<br />
<br />
{{Note|The owner of tty ''must'' match with the user for which pinentry is running. Being part of the group {{Ic|tty}} '''is not''' enough.}}<br />
<br />
=== Agent complains end of file ===<br />
<br />
The default pinentry program is pinentry-gtk-2, which needs a DBus session bus to run properly. See [[General troubleshooting#Session permissions]] for details.<br />
<br />
Alternatively, you can use {{ic|pinentry-qt}}. See [[GnuPG#Pinentry]].<br />
<br />
=== KGpg configuration permissions ===<br />
<br />
There have been issues with {{Pkg|kdeutils-kgpg}} being able to access the {{ic|~/.gnupg/}} options. One issue might be a result of a deprecated ''options'' file, see the [https://bugs.kde.org/show_bug.cgi?id=290221 bug] report.<br />
<br />
Another user reported that ''KGpg'' failed to start until the {{ic|~/.gnupg}} folder is set to {{ic|drwxr-xr-x}} permissions. If you require this work-around, ensure that the directory contents retain {{ic|-rw-------}} permissions! Further, report it as a bug to the [https://bugs.kde.org/buglist.cgi?quicksearch=kgpg developers].<br />
<br />
=== Conflicts between gnome-keyring and gpg-agent ===<br />
<br />
{{Accuracy|See [[#GPG_AGENT_INFO]]}}<br />
<br />
While the Gnome keyring implements a GPG agent component, as of GnuPG version 2.1, GnuPG ignores the {{ic|GPG_AGENT_INFO}} environment variable, so that Gnome keyring can no longer be used as a GPG agent.<br />
<br />
=== mutt and gpg ===<br />
<br />
To be asked for your GnuPG password only once per session as of GnuPG 2.1, see [https://bbs.archlinux.org/viewtopic.php?pid=1490821#p1490821 this forum thread].<br />
<br />
=== "Lost" keys, upgrading to gnupg version 2.1 ===<br />
<br />
When {{ic|gpg --list-keys}} fails to show keys that used to be there, and applications complain about missing or invalid keys, some keys may not have been migrated to the new format.<br />
<br />
Please read [http://jo-ke.name/wp/?p=111 GnuPG invalid packet workaround]. Basically, it says that there is a bug with keys in the old {{ic|pubring.gpg}} and {{ic|secring.gpg}} files, which have now been superseded by the new {{ic|pubring.kbx}} file and the {{ic|private-keys-v1.d/}} subdirectory and files. Your missing keys can be recovered with the following commnads:<br />
<br />
$ cd<br />
$ cp -r .gnupg gnupgOLD<br />
$ gpg --export-ownertrust > otrust.txt<br />
$ gpg --import .gnupg/pubring.gpg<br />
$ gpg --import-ownertrust otrust.txt<br />
$ gpg --list-keys<br />
<br />
== See also ==<br />
<br />
* [http://gnupg.org/gph/en/manual.html The GNU Privacy Handbook]<br />
* [http://blog.sanctum.geek.nz/series/linux-crypto/ A more comprehensive gpg Tutorial]<br />
* [https://www.gnupg.org/faq/gnupg-faq.html GnuPG FAQ]<br />
* [https://help.riseup.net/en/security/message-security/openpgp/gpg-best-practices gpg.conf recommendations and best practices]<br />
* [https://github.com/ioerror/torbirdy/blob/master/gpg.conf Torbirdy gpg.conf]</div>Chehrihttps://wiki.archlinux.org/index.php?title=Git&diff=368670Git2015-04-05T19:06:40Z<p>Chehri: Moved the new sections into the correct group.</p>
<hr />
<div>[[Category:Version Control System]]<br />
[[zh-CN:Git]]<br />
{{Related articles start}}<br />
{{Related|Super Quick Git Guide}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
<br />
[[wikipedia:Git_%28software%29|Git]] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain sources for the Linux kernel as well as thousands of other projects, including a number of Arch Linux projects. <br />
<br />
== Installation ==<br />
<br />
[[Install]] {{Pkg|git}} from the [[official repositories]].<br />
<br />
If you want to use Git's built-in GUI tools (e.g. ''gitk'' or ''git gui''), make sure you have installed the {{Pkg|tk}} package, or they will refuse to start with a cryptic error:<br />
<br />
/usr/bin/gitk: line 3: exec: wish: not found.<br />
<br />
Also, the GUI tools require {{pkg|gsfonts}}, or they will crash with a segmentation fault.<br />
<br />
If you want to use the Git SVN bridge (''git svn'') you will need {{pkg|perl-term-readkey}}, or you will receive the following error: <br />
<br />
Can't locate Term/ReadKey.pm in @INC (you may need to install the Term::ReadKey module)<br />
<br />
== Basic configuration ==<br />
<br />
In order to use Git you need to set at least a name and email:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@foobar.com''"<br />
<br />
See [[#Advanced configuration]] for more settings.<br />
<br />
== Basic usage ==<br />
<br />
This tutorial teaches how to use Git for basic distributed revision control of a project. A typical Git workflow is generally:<br />
<br />
# Create a new project or clone a remote one.<br />
# Create a branch to make changes; then commit those changes.<br />
# Consolidate commits for better organization/understanding.<br />
# Merge commits back into the main branch.<br />
# (Optional) Push changes to a remote server.<br />
<br />
=== Local repository ===<br />
<br />
==== Create a repository ====<br />
<br />
Initialize a new repository:<br />
<br />
$ git init<br />
<br />
Add files to the repository index:<br />
<br />
$ git add ''file1'' ''file2''<br />
<br />
Or, to add all files:<br />
<br />
$ git add .<br />
<br />
{{Tip|To use ''git add'' and have some files ignored, create a {{ic|.gitignore}} file:<br />
<br />
{{hc|.gitignore|<br />
# File I'll likely delete<br />
test-script<br />
}}<br />
}}<br />
<br />
Remove a file:<br />
<br />
$ git rm ''file''<br />
<br />
Rename a file:<br />
<br />
$ git mv ''file1'' ''file2''<br />
<br />
List files:<br />
<br />
$ git ls-files<br />
<br />
==== Commit changes ====<br />
<br />
In order to record the changes to the repository, they must first be added to the ''index'', or ''staging area'', with an operation often also referred to as ''staging''. This is done with the ''git add'' command:<br />
<br />
$ git add ''file''<br />
<br />
Once the content to be recorded is staged, it can be ''committed'' to the repository:<br />
<br />
$ git commit --message "First commit."<br />
<br />
The {{ic|--message}} option is for a short message: if omitted, the preset editor will be spawned to allow entering a longer message.<br />
<br />
{{Tip|<br />
* Always commit small changes frequently and with meaningful messages.<br />
* If you want to add all the modified files to the index, and commit them in a single command, do:<br />
<br />
$ git commit --all --message "First commit."<br />
}}<br />
<br />
To go back and edit the commit message:<br />
<br />
$ git commit --amend<br />
<br />
Many of the commands in this article take commits as arguments. A commit can be identified by any of the following:<br />
<br />
* Its 40-digit SHA-1 hash (the first 7 digits are usually sufficient to identify it uniquely)<br />
* Any commit label such as a branch or tag name<br />
* The label {{ic|HEAD}} always refers to the currently checked-out commit (usually the head of the branch, unless you used {{ic|git checkout}} to jump back in history to an old commit)<br />
* Any of the above plus {{ic|~}} to refer to previous commits. For example, {{ic|HEAD~}} refers to one commit before {{ic|HEAD}} and {{ic|HEAD~5}} refers to five commits before {{ic|HEAD}}.<br />
<br />
==== View changes ====<br />
<br />
Show differences between commits:<br />
<br />
$ git diff<br />
<br />
To get a general overview of the changes:<br />
<br />
$ git status<br />
<br />
View history of changes with:<br />
<br />
$ git log<br />
<br />
==== Branch a repository ====<br />
<br />
Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch. Branch names should reflect the alteration accurately:<br />
<br />
$ git branch help-section-addition<br />
<br />
To see the created branches:<br />
<br />
$ git branch<br />
<br />
To switch to a branch:<br />
<br />
$ git checkout ''branch''<br />
<br />
To create and switch to a branch in one step:<br />
<br />
$ git checkout -b ''branch''<br />
<br />
To merge a branch back to the master branch:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
The changes will be merged if they do not conflict. If they do, the conflicts will be recorded. What is causing the conflicts can been seen with {{ic|git diff}}, then conflict resolution will need to be done manually.<br />
<br />
When done with a branch, it can be deleted by:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== Collaboration ===<br />
<br />
==== Adopting a good etiquette ====<br />
<br />
* When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.<br />
* Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the [[#History and versioning|log]] of the repository.<br />
* When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.<br />
* If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.<br />
<br />
==== Clone a repository ====<br />
<br />
To begin contributing to a project start by cloning its repository:<br />
<br />
$ git clone ''location'' ''folder''<br />
<br />
{{ic|''location''}} can be either a path or network address. Also, when cloning is done, the location is recorded so just a {{ic|git pull}} will be needed later.<br />
<br />
==== Pull requests ====<br />
<br />
After making and committing some changes, the contributor can ask the original author to the merge them; this is called a "pull request".<br />
<br />
The original author can merge the changes by doing:<br />
<br />
$ git pull ''location'' master<br />
<br />
The ''pull'' command fetches the changes and attempts to merge them. If there are conflicts (e.g. the original author made changes in the same time span) then it will be necessary to manually fix them.<br />
<br />
Alternatively, the original author can pick the changes wanting to be incorporated. Using the fetch option (and log option with a special {{ic|FETCH_HEAD}} symbol) the contents of the pull request can be viewed before deciding what to do:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== Using remotes ====<br />
<br />
Remotes are tracked repositories, a {{ic|''label''}} defining a location. They are commonly used for frequently accessed repositories.<br />
<br />
$ git remote add ''label'' ''location''<br />
$ git fetch ''label''<br />
$ git log -p master..''label''/master<br />
<br />
Remotes for the current repository can be viewed with:<br />
<br />
$ git remote -v<br />
<br />
When defining a remote that is a parent of the fork (the project lead), it is defined as ''upstream''.<br />
<br />
==== Push to a repository ====<br />
<br />
If the contributor is given the rights from the original authors, the changes can be pushed:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
When {{ic|git clone}} is performed it records the original location and gives it a remote name of {{ic|origin}}. So what is typically done is this:<br />
<br />
$ git push origin master<br />
<br />
If the {{ic|--set-upstream}} option is used, the location is recorded so the next time just a {{ic|git push}} is necessary.<br />
<br />
==== Dealing with merges ====<br />
<br />
See [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts Basic Merge Conflicts] in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the {{ic|--abort}} command (e.g. {{ic|git merge --abort}} or {{ic|git pull --abort}}).<br />
<br />
=== History and versioning ===<br />
<br />
==== Searching the history ====<br />
<br />
{{ic|git log}} will give the history with a commit checksum, author, date, and the short message. To see the long message (the checksum can be truncated as long as it is unique):<br />
<br />
$ git show ''checksum''<br />
<br />
To show details of the last commit:<br />
<br />
$ git show HEAD<br />
<br />
To search through files of a previous commit it can be done with:<br />
<br />
$ git grep ''checksum''<br />
<br />
Ranges can also be specified:<br />
<br />
$ git grep ''tag2''..''tag4''<br />
<br />
==== Versioning for release ====<br />
<br />
For versioning, commits can be tagged:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
Tagging is generally done for [https://www.drupal.org/node/1066342 releasing/versioning] but it can be any string. Generally annotated tags are used because they get added to the Git database. To tag the current commit:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
Tags can be listed and deleted with:<br />
<br />
$ git tag -l<br />
$ git tag -d 2.08<br />
<br />
Tags that have to be updated remotely, have to be done so separately:<br />
<br />
$ git push --tags<br />
<br />
==== Organizing commits ====<br />
<br />
Before submitting a pull request it may be desirable to consolidate/organize the commits. This is done with the {{ic|git rebase}} interactive option:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
This will open the editor with a summary of all the commits in the range specified; in this case including the newest ({{ic|HEAD}}) to, but excluding, {{ic|''checksum''}}. Or to use a number notation, use for example {{ic|HEAD~3}}, which will rebase the last three commits.<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
Editing the action in the first column will dictate how the rebase will be done. The options are:<br />
<br />
* {{ic|pick}} — Apply this commit as is (the default).<br />
* {{ic|edit}} — Edit files and/or commit message.<br />
* {{ic|reword}} — Edit commit message.<br />
* {{ic|squash}} — Merge/fold into previous commit.<br />
* {{ic|fixup}} — Merge/fold into previous commit discarding its message.<br />
<br />
The commits can be re-ordered or erased from the history (but be very careful with these). After editing the file, Git will perform the specified actions; if prompted to resolve merge problems, fix them and continue with {{ic|git rebase --continue}} or back out with the {{ic|git rebase --abort}} command.<br />
<br />
{{Note|Squashing commits is only used for local commits, it will cause troubles on a repository that is shared by other people.}}<br />
<br />
== Advanced configuration ==<br />
<br />
Git reads its configuration from a few INI-type configuration files:<br />
<br />
* Each repository contains a {{ic|.git/config}} file for specific configuration.<br />
* Each user has a {{ic|$HOME/.gitconfig}} file for fallback values.<br />
* {{ic|/etc/gitconfig}} is used for system-wide defaults.<br />
<br />
These files can be edited directly, but the usual method is to use the ''git-config'' utility as shown in the examples below.<br />
<br />
To list the currently set variables:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
The default editor is [[vim]] but to set it to [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
To set a default push action:<br />
<br />
$ git config --global push.default simple<br />
<br />
To set a tool for ''git difftool'' (by default it is ''meld''):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
See [https://www.kernel.org/pub/software/scm/git/docs/git-config.html git-config(1)] and [http://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration] for more information.<br />
<br />
=== Speeding up SSH ===<br />
<br />
Often if you find yourself pushing constantly to a few common servers, you may wish to remove the hassle of setting your username for each repository. <br />
<br />
If you don't already have the keys created, make them now.<br />
<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/aur -C "user@domain.com"<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/github -C "user@domain.com"<br />
<br />
Add the resulting public keys to your accounts.<br />
<br />
Additionally, reusing the same SSH connection will drastically improve the time {{ic|git push}} takes.<br />
<br />
$ mkdir -p ~/.ssh/sockets/<br />
<br />
You may wish to adjust the {{ic|ServerAliveInterval}} depending on your connection.<br />
<br />
{{hc|~/.ssh/config|<br />
Host *<br />
ControlMaster auto<br />
ControlPath ~/.ssh/sockets/%r@%h-%p<br />
ControlPersist 8760h<br />
ServerAliveInterval 5<br />
ServerAliveCountMax 1<br />
TCPKeepAlive yes<br />
<br />
Host aur-dev.archlinux.org<br />
IdentityFile ~/.ssh/aur<br />
User aur<br />
Port 2222<br />
<br />
Host github.com<br />
IdentityFile ~/.ssh/github<br />
User [username here]<br />
}}<br />
<br />
=== Git + SSH ===<br />
<br />
While using the Git protocol is faster than HTTP, it only provides read access. Using a combination of SSH for pushing and Git for pulling might be useful for any server that offers both these services. For example, the following config will set that for any repository hosted on GitHub.<br />
<br />
{{hc|~/.gitconfig|<br />
[url "ssh://git@github.com/"]<br />
pushInsteadOf &#61; https://github.com/<br />
[url "git://github.com/"]<br />
insteadOf &#61; https://github.com/<br />
}}<br />
<br />
{{Note|Some corporate firewalls block port 9418/TCP, which the Git protocol uses. In those situations, HTTPS will likely be the best option.}}<br />
<br />
=== Bash completion ===<br />
<br />
In order to enable Bash completion, source {{ic|/usr/share/git/completion/git-completion.bash}} in a [[Bash#Configuration_files|Bash startup file]]. Alternatively, install {{pkg|bash-completion}}.<br />
<br />
=== Git prompt ===<br />
<br />
The Git package comes with a prompt script. To enable it, source the {{ic|/usr/share/git/completion/git-prompt.sh}} script in a [[Autostarting#Shells|shell startup file]], then set a custom prompt with the {{ic|%s}} parameter:<br />
<br />
* For [[Bash]]: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* For [[zsh]]: {{ic|1=PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || '''+''' for staged, '''*''' if unstaged. <br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || '''$''' if something is stashed.<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || '''%''' if there are untracked files.<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' behind, ahead, or diverged from upstream.<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} will need to be set to {{ic|auto}} for changes to take effect.<br />
<br />
{{Note|If you experience that {{ic|$(__git_ps1)}} returns {{ic|((unknown))}}, then there's a {{ic|.git}} folder in your current directory which does not contain any repository, and therefore Git does not recognize it. This can, for example, happen if you mistake Git's configuration file to be {{ic|~/.git/config}} instead of {{ic|~/.gitconfig}}.}}<br />
<br />
== Advanced usage ==<br />
<br />
To view get an idea of the amount of work done:<br />
<br />
$ git diff --stat<br />
<br />
Git log with forking representation:<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
Git log graph alias (i.e. {{ic|git graph}} will show the previous):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
Reset to previous commit (very dangerous, erases everything to specified commit):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
If a repository address gets changed, its remote location will need to be updated:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):<br />
<br />
$ git commit -s<br />
<br />
Signed-off-by automatically append to patches (when using {{ic|git format-patch ''commit''}}):<br />
<br />
$ git config --local format.signoff true<br />
<br />
Commit specific parts of files that have changed. This is useful if there are a large number of changes made that would be best split into several commits:<br />
<br />
$ git add -p<br />
<br />
=== Working with a non-master branch ===<br />
<br />
Occasionally a maintainer will ask that work be done on a branch. These branches are often called {{ic|devel}} or {{ic|testing}}. Begin by cloning the repository.<br />
<br />
To enter another branch beside master ({{ic|git clone}} only shows master branch but others still exist, {{ic|git branch -a}} to show):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
Now edit normally; however to keep the repository tree in sync be sure to use both:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
== Git server ==<br />
<br />
How to set up connecting to repositories using varying protocols.<br />
<br />
=== SSH ===<br />
<br />
To use the SSH protocol, first set up a public SSH key; for that follow the guide at [[SSH keys]]. To set up a SSH server, follow the [[SSH]] guide.<br />
<br />
With SSH working and a key generated, paste the contents of {{ic|~/.ssh/id_rsa.pub}} to {{ic|~/.ssh/authorized_keys}} (be sure it is all on one line). Now the Git repository can be accessed with SSH by doing:<br />
<br />
$ git clone user@foobar.com:repository-name.git<br />
<br />
You should now get an SSH yes/no question, if you have the SSH client setting {{ic|StrictHostKeyChecking}} set to {{ic|ask}} (the default). Type {{ic|yes}} followed by {{ic|Enter}}. Then you should have your repository checked out. Because this is with SSH, you also have commit rights now.<br />
<br />
To modify an existing repository to use SSH, the remote location will need to be redefined:<br />
<br />
$ git remote set-url origin git@localhost:my_repository.git<br />
<br />
Connecting on a port other than 22 can be configured on a per-host basis in {{ic|/etc/ssh/ssh_config}} or {{ic|~/.ssh/config}}. To set up ports for a repository, specify the path in {{ic|.git/config}}. It will have a format like this if the repository is in the home directory and is using 443 for the port:<br />
<br />
<nowiki>url = ssh://user@foobar.com:443/~repository-name/repo.git</nowiki><br />
<br />
=== Smart HTTP ===<br />
<br />
Git is able to use the HTTP(S) protocol as efficiently as the SSH or Git protocols, by utilizing the git-http-backend. Furthermore it is not only possible to clone or pull from repositories, but also to push into repositories over HTTP(S).<br />
<br />
The setup for this is rather simple as all you need to have installed is the Apache web server ({{pkg|apache}}, with {{ic|mod_cgi}}, {{ic|mod_alias}}, and {{ic|mod_env}} enabled) and of course, {{pkg|git}}.<br />
<br />
Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at {{ic|/etc/httpd/conf/httpd.conf}}:<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
<br />
The above example configuration assumes that your Git repositories are located at {{ic|/srv/git}} and that you want to access them via something like <nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>. Feel free to customize this to your needs.<br />
<br />
{{Note|Of course, you have to make sure that Apache can read and write (if you want to enable push access) to your Git repositories.}}<br />
<br />
For more detailed documentation, visit the following links:<br />
* http://progit.org/2010/03/04/smart-http.html<br />
* https://www.kernel.org/pub/software/scm/git/docs/v1.7.10.1/git-http-backend.html<br />
<br />
=== Git ===<br />
<br />
{{Note|The Git protocol only allows read access.}}<br />
<br />
[[start|Start and enable]] {{ic|git-daemon.socket}}.<br />
<br />
The daemon is started with the following options:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
Repositories placed in {{ic|/srv/git/}} will be recognized by the daemon. Clients can connect with something similar to:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== Setting access rights ===<br />
<br />
To restrict read and/or write access, use standard Unix permissions. Refer to http://sitaramc.github.com/gitolite/doc/overkill.html{{Dead link|2013|11|06}} ([https://web.archive.org/web/20111004134500/http://sitaramc.github.com/gitolite/doc/overkill.html archive.org mirror]) for more information.<br />
<br />
For fine-grained access management, refer to [[gitolite]] and [[gitosis]].<br />
<br />
== See also ==<br />
<br />
* [http://git-scm.com/book Pro Git book]<br />
* [http://gitref.org/ Git Reference]<br />
* https://www.kernel.org/pub/software/scm/git/docs/<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request Git overall]<br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git overall2]<br />
* https://wiki.videolan.org/Git<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols offered by GitHub]</div>Chehrihttps://wiki.archlinux.org/index.php?title=Git&diff=368669Git2015-04-05T19:03:43Z<p>Chehri: Added more info on the Git protocol and using SSH.</p>
<hr />
<div>[[Category:Version Control System]]<br />
[[zh-CN:Git]]<br />
{{Related articles start}}<br />
{{Related|Super Quick Git Guide}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
<br />
[[wikipedia:Git_%28software%29|Git]] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain sources for the Linux kernel as well as thousands of other projects, including a number of Arch Linux projects. <br />
<br />
== Installation ==<br />
<br />
[[Install]] {{Pkg|git}} from the [[official repositories]].<br />
<br />
If you want to use Git's built-in GUI tools (e.g. ''gitk'' or ''git gui''), make sure you have installed the {{Pkg|tk}} package, or they will refuse to start with a cryptic error:<br />
<br />
/usr/bin/gitk: line 3: exec: wish: not found.<br />
<br />
Also, the GUI tools require {{pkg|gsfonts}}, or they will crash with a segmentation fault.<br />
<br />
If you want to use the Git SVN bridge (''git svn'') you will need {{pkg|perl-term-readkey}}, or you will receive the following error: <br />
<br />
Can't locate Term/ReadKey.pm in @INC (you may need to install the Term::ReadKey module)<br />
<br />
== Basic configuration ==<br />
<br />
In order to use Git you need to set at least a name and email:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@foobar.com''"<br />
<br />
See [[#Advanced configuration]] for more settings.<br />
<br />
== Basic usage ==<br />
<br />
This tutorial teaches how to use Git for basic distributed revision control of a project. A typical Git workflow is generally:<br />
<br />
# Create a new project or clone a remote one.<br />
# Create a branch to make changes; then commit those changes.<br />
# Consolidate commits for better organization/understanding.<br />
# Merge commits back into the main branch.<br />
# (Optional) Push changes to a remote server.<br />
<br />
=== Local repository ===<br />
<br />
==== Create a repository ====<br />
<br />
Initialize a new repository:<br />
<br />
$ git init<br />
<br />
Add files to the repository index:<br />
<br />
$ git add ''file1'' ''file2''<br />
<br />
Or, to add all files:<br />
<br />
$ git add .<br />
<br />
{{Tip|To use ''git add'' and have some files ignored, create a {{ic|.gitignore}} file:<br />
<br />
{{hc|.gitignore|<br />
# File I'll likely delete<br />
test-script<br />
}}<br />
}}<br />
<br />
Remove a file:<br />
<br />
$ git rm ''file''<br />
<br />
Rename a file:<br />
<br />
$ git mv ''file1'' ''file2''<br />
<br />
List files:<br />
<br />
$ git ls-files<br />
<br />
==== Commit changes ====<br />
<br />
In order to record the changes to the repository, they must first be added to the ''index'', or ''staging area'', with an operation often also referred to as ''staging''. This is done with the ''git add'' command:<br />
<br />
$ git add ''file''<br />
<br />
Once the content to be recorded is staged, it can be ''committed'' to the repository:<br />
<br />
$ git commit --message "First commit."<br />
<br />
The {{ic|--message}} option is for a short message: if omitted, the preset editor will be spawned to allow entering a longer message.<br />
<br />
{{Tip|<br />
* Always commit small changes frequently and with meaningful messages.<br />
* If you want to add all the modified files to the index, and commit them in a single command, do:<br />
<br />
$ git commit --all --message "First commit."<br />
}}<br />
<br />
To go back and edit the commit message:<br />
<br />
$ git commit --amend<br />
<br />
Many of the commands in this article take commits as arguments. A commit can be identified by any of the following:<br />
<br />
* Its 40-digit SHA-1 hash (the first 7 digits are usually sufficient to identify it uniquely)<br />
* Any commit label such as a branch or tag name<br />
* The label {{ic|HEAD}} always refers to the currently checked-out commit (usually the head of the branch, unless you used {{ic|git checkout}} to jump back in history to an old commit)<br />
* Any of the above plus {{ic|~}} to refer to previous commits. For example, {{ic|HEAD~}} refers to one commit before {{ic|HEAD}} and {{ic|HEAD~5}} refers to five commits before {{ic|HEAD}}.<br />
<br />
==== View changes ====<br />
<br />
Show differences between commits:<br />
<br />
$ git diff<br />
<br />
To get a general overview of the changes:<br />
<br />
$ git status<br />
<br />
View history of changes with:<br />
<br />
$ git log<br />
<br />
==== Branch a repository ====<br />
<br />
Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch. Branch names should reflect the alteration accurately:<br />
<br />
$ git branch help-section-addition<br />
<br />
To see the created branches:<br />
<br />
$ git branch<br />
<br />
To switch to a branch:<br />
<br />
$ git checkout ''branch''<br />
<br />
To create and switch to a branch in one step:<br />
<br />
$ git checkout -b ''branch''<br />
<br />
To merge a branch back to the master branch:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
The changes will be merged if they do not conflict. If they do, the conflicts will be recorded. What is causing the conflicts can been seen with {{ic|git diff}}, then conflict resolution will need to be done manually.<br />
<br />
When done with a branch, it can be deleted by:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== Collaboration ===<br />
<br />
==== Adopting a good etiquette ====<br />
<br />
* When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.<br />
* Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the [[#History and versioning|log]] of the repository.<br />
* When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.<br />
* If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.<br />
<br />
==== Clone a repository ====<br />
<br />
To begin contributing to a project start by cloning its repository:<br />
<br />
$ git clone ''location'' ''folder''<br />
<br />
{{ic|''location''}} can be either a path or network address. Also, when cloning is done, the location is recorded so just a {{ic|git pull}} will be needed later.<br />
<br />
==== Pull requests ====<br />
<br />
After making and committing some changes, the contributor can ask the original author to the merge them; this is called a "pull request".<br />
<br />
The original author can merge the changes by doing:<br />
<br />
$ git pull ''location'' master<br />
<br />
The ''pull'' command fetches the changes and attempts to merge them. If there are conflicts (e.g. the original author made changes in the same time span) then it will be necessary to manually fix them.<br />
<br />
Alternatively, the original author can pick the changes wanting to be incorporated. Using the fetch option (and log option with a special {{ic|FETCH_HEAD}} symbol) the contents of the pull request can be viewed before deciding what to do:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== Using remotes ====<br />
<br />
Remotes are tracked repositories, a {{ic|''label''}} defining a location. They are commonly used for frequently accessed repositories.<br />
<br />
$ git remote add ''label'' ''location''<br />
$ git fetch ''label''<br />
$ git log -p master..''label''/master<br />
<br />
Remotes for the current repository can be viewed with:<br />
<br />
$ git remote -v<br />
<br />
When defining a remote that is a parent of the fork (the project lead), it is defined as ''upstream''.<br />
<br />
==== Push to a repository ====<br />
<br />
If the contributor is given the rights from the original authors, the changes can be pushed:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
When {{ic|git clone}} is performed it records the original location and gives it a remote name of {{ic|origin}}. So what is typically done is this:<br />
<br />
$ git push origin master<br />
<br />
If the {{ic|--set-upstream}} option is used, the location is recorded so the next time just a {{ic|git push}} is necessary.<br />
<br />
==== Dealing with merges ====<br />
<br />
See [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts Basic Merge Conflicts] in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the {{ic|--abort}} command (e.g. {{ic|git merge --abort}} or {{ic|git pull --abort}}).<br />
<br />
=== History and versioning ===<br />
<br />
==== Searching the history ====<br />
<br />
{{ic|git log}} will give the history with a commit checksum, author, date, and the short message. To see the long message (the checksum can be truncated as long as it is unique):<br />
<br />
$ git show ''checksum''<br />
<br />
To show details of the last commit:<br />
<br />
$ git show HEAD<br />
<br />
To search through files of a previous commit it can be done with:<br />
<br />
$ git grep ''checksum''<br />
<br />
Ranges can also be specified:<br />
<br />
$ git grep ''tag2''..''tag4''<br />
<br />
==== Versioning for release ====<br />
<br />
For versioning, commits can be tagged:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
Tagging is generally done for [https://www.drupal.org/node/1066342 releasing/versioning] but it can be any string. Generally annotated tags are used because they get added to the Git database. To tag the current commit:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
Tags can be listed and deleted with:<br />
<br />
$ git tag -l<br />
$ git tag -d 2.08<br />
<br />
Tags that have to be updated remotely, have to be done so separately:<br />
<br />
$ git push --tags<br />
<br />
==== Organizing commits ====<br />
<br />
Before submitting a pull request it may be desirable to consolidate/organize the commits. This is done with the {{ic|git rebase}} interactive option:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
This will open the editor with a summary of all the commits in the range specified; in this case including the newest ({{ic|HEAD}}) to, but excluding, {{ic|''checksum''}}. Or to use a number notation, use for example {{ic|HEAD~3}}, which will rebase the last three commits.<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
Editing the action in the first column will dictate how the rebase will be done. The options are:<br />
<br />
* {{ic|pick}} — Apply this commit as is (the default).<br />
* {{ic|edit}} — Edit files and/or commit message.<br />
* {{ic|reword}} — Edit commit message.<br />
* {{ic|squash}} — Merge/fold into previous commit.<br />
* {{ic|fixup}} — Merge/fold into previous commit discarding its message.<br />
<br />
The commits can be re-ordered or erased from the history (but be very careful with these). After editing the file, Git will perform the specified actions; if prompted to resolve merge problems, fix them and continue with {{ic|git rebase --continue}} or back out with the {{ic|git rebase --abort}} command.<br />
<br />
{{Note|Squashing commits is only used for local commits, it will cause troubles on a repository that is shared by other people.}}<br />
<br />
== Advanced configuration ==<br />
<br />
Git reads its configuration from a few INI-type configuration files:<br />
<br />
* Each repository contains a {{ic|.git/config}} file for specific configuration.<br />
* Each user has a {{ic|$HOME/.gitconfig}} file for fallback values.<br />
* {{ic|/etc/gitconfig}} is used for system-wide defaults.<br />
<br />
These files can be edited directly, but the usual method is to use the ''git-config'' utility as shown in the examples below.<br />
<br />
To list the currently set variables:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
The default editor is [[vim]] but to set it to [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
To set a default push action:<br />
<br />
$ git config --global push.default simple<br />
<br />
To set a tool for ''git difftool'' (by default it is ''meld''):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
See [https://www.kernel.org/pub/software/scm/git/docs/git-config.html git-config(1)] and [http://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration] for more information.<br />
<br />
=== Bash completion ===<br />
<br />
In order to enable Bash completion, source {{ic|/usr/share/git/completion/git-completion.bash}} in a [[Bash#Configuration_files|Bash startup file]]. Alternatively, install {{pkg|bash-completion}}.<br />
<br />
=== Git prompt ===<br />
<br />
The Git package comes with a prompt script. To enable it, source the {{ic|/usr/share/git/completion/git-prompt.sh}} script in a [[Autostarting#Shells|shell startup file]], then set a custom prompt with the {{ic|%s}} parameter:<br />
<br />
* For [[Bash]]: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* For [[zsh]]: {{ic|1=PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || '''+''' for staged, '''*''' if unstaged. <br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || '''$''' if something is stashed.<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || '''%''' if there are untracked files.<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' behind, ahead, or diverged from upstream.<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} will need to be set to {{ic|auto}} for changes to take effect.<br />
<br />
{{Note|If you experience that {{ic|$(__git_ps1)}} returns {{ic|((unknown))}}, then there's a {{ic|.git}} folder in your current directory which does not contain any repository, and therefore Git does not recognize it. This can, for example, happen if you mistake Git's configuration file to be {{ic|~/.git/config}} instead of {{ic|~/.gitconfig}}.}}<br />
<br />
== Advanced usage ==<br />
<br />
To view get an idea of the amount of work done:<br />
<br />
$ git diff --stat<br />
<br />
Git log with forking representation:<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
Git log graph alias (i.e. {{ic|git graph}} will show the previous):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
Reset to previous commit (very dangerous, erases everything to specified commit):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
If a repository address gets changed, its remote location will need to be updated:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):<br />
<br />
$ git commit -s<br />
<br />
Signed-off-by automatically append to patches (when using {{ic|git format-patch ''commit''}}):<br />
<br />
$ git config --local format.signoff true<br />
<br />
Commit specific parts of files that have changed. This is useful if there are a large number of changes made that would be best split into several commits:<br />
<br />
$ git add -p<br />
<br />
=== Working with a non-master branch ===<br />
<br />
Occasionally a maintainer will ask that work be done on a branch. These branches are often called {{ic|devel}} or {{ic|testing}}. Begin by cloning the repository.<br />
<br />
To enter another branch beside master ({{ic|git clone}} only shows master branch but others still exist, {{ic|git branch -a}} to show):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
Now edit normally; however to keep the repository tree in sync be sure to use both:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
== Git server ==<br />
<br />
How to set up connecting to repositories using varying protocols.<br />
<br />
=== SSH ===<br />
<br />
To use the SSH protocol, first set up a public SSH key; for that follow the guide at [[SSH keys]]. To set up a SSH server, follow the [[SSH]] guide.<br />
<br />
With SSH working and a key generated, paste the contents of {{ic|~/.ssh/id_rsa.pub}} to {{ic|~/.ssh/authorized_keys}} (be sure it is all on one line). Now the Git repository can be accessed with SSH by doing:<br />
<br />
$ git clone user@foobar.com:repository-name.git<br />
<br />
You should now get an SSH yes/no question, if you have the SSH client setting {{ic|StrictHostKeyChecking}} set to {{ic|ask}} (the default). Type {{ic|yes}} followed by {{ic|Enter}}. Then you should have your repository checked out. Because this is with SSH, you also have commit rights now.<br />
<br />
To modify an existing repository to use SSH, the remote location will need to be redefined:<br />
<br />
$ git remote set-url origin git@localhost:my_repository.git<br />
<br />
Connecting on a port other than 22 can be configured on a per-host basis in {{ic|/etc/ssh/ssh_config}} or {{ic|~/.ssh/config}}. To set up ports for a repository, specify the path in {{ic|.git/config}}. It will have a format like this if the repository is in the home directory and is using 443 for the port:<br />
<br />
<nowiki>url = ssh://user@foobar.com:443/~repository-name/repo.git</nowiki><br />
<br />
==== Speeding up SSH ====<br />
<br />
Often if you find yourself pushing constantly to a few common servers, you may wish to remove the hassle of setting your username for each repository. <br />
<br />
If you don't already have the keys created, make them now.<br />
<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/aur -C "user@domain.com"<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/github -C "user@domain.com"<br />
<br />
Add the resulting public keys to your accounts.<br />
<br />
Additionally, reusing the same SSH connection will drastically improve the time {{ic|git push}} takes.<br />
<br />
$ mkdir -p ~/.ssh/sockets/<br />
<br />
You may wish to adjust the {{ic|ServerAliveInterval}} depending on your connection.<br />
<br />
{{hc|~/.ssh/config|<br />
Host *<br />
ControlMaster auto<br />
ControlPath ~/.ssh/sockets/%r@%h-%p<br />
ControlPersist 8760h<br />
ServerAliveInterval 5<br />
ServerAliveCountMax 1<br />
TCPKeepAlive yes<br />
<br />
Host aur-dev.archlinux.org<br />
IdentityFile ~/.ssh/aur<br />
User aur<br />
Port 2222<br />
<br />
Host github.com<br />
IdentityFile ~/.ssh/github<br />
User [username here]<br />
}}<br />
<br />
=== Smart HTTP ===<br />
<br />
Git is able to use the HTTP(S) protocol as efficiently as the SSH or Git protocols, by utilizing the git-http-backend. Furthermore it is not only possible to clone or pull from repositories, but also to push into repositories over HTTP(S).<br />
<br />
The setup for this is rather simple as all you need to have installed is the Apache web server ({{pkg|apache}}, with {{ic|mod_cgi}}, {{ic|mod_alias}}, and {{ic|mod_env}} enabled) and of course, {{pkg|git}}.<br />
<br />
Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at {{ic|/etc/httpd/conf/httpd.conf}}:<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
<br />
The above example configuration assumes that your Git repositories are located at {{ic|/srv/git}} and that you want to access them via something like <nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>. Feel free to customize this to your needs.<br />
<br />
{{Note|Of course, you have to make sure that Apache can read and write (if you want to enable push access) to your Git repositories.}}<br />
<br />
For more detailed documentation, visit the following links:<br />
* http://progit.org/2010/03/04/smart-http.html<br />
* https://www.kernel.org/pub/software/scm/git/docs/v1.7.10.1/git-http-backend.html<br />
<br />
=== Git ===<br />
<br />
{{Note|The Git protocol only allows read access.}}<br />
<br />
[[start|Start and enable]] {{ic|git-daemon.socket}}.<br />
<br />
The daemon is started with the following options:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
Repositories placed in {{ic|/srv/git/}} will be recognized by the daemon. Clients can connect with something similar to:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
{{Note|Some corporate firewalls block port 9418/TCP, which the Git protocol uses. In those situations, HTTPS will likely be the best option.}}<br />
<br />
=== Git + SSH ===<br />
<br />
While using the Git protocol is faster than HTTP, it only provides read access. Using a combination of SSH for pushing and Git for pulling might be useful for any server that offers both these services. For example, the following config will set that for any repository hosted on GitHub.<br />
<br />
{{hc|~/.gitconfig|<br />
[url "ssh://git@github.com/"]<br />
pushInsteadOf &#61; https://github.com/<br />
[url "git://github.com/"]<br />
insteadOf &#61; https://github.com/<br />
}}<br />
<br />
=== Setting access rights ===<br />
<br />
To restrict read and/or write access, use standard Unix permissions. Refer to http://sitaramc.github.com/gitolite/doc/overkill.html{{Dead link|2013|11|06}} ([https://web.archive.org/web/20111004134500/http://sitaramc.github.com/gitolite/doc/overkill.html archive.org mirror]) for more information.<br />
<br />
For fine-grained access management, refer to [[gitolite]] and [[gitosis]].<br />
<br />
== See also ==<br />
<br />
* [http://git-scm.com/book Pro Git book]<br />
* [http://gitref.org/ Git Reference]<br />
* https://www.kernel.org/pub/software/scm/git/docs/<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request Git overall]<br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git overall2]<br />
* https://wiki.videolan.org/Git<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols offered by GitHub]</div>Chehrihttps://wiki.archlinux.org/index.php?title=Git&diff=368522Git2015-04-04T17:43:05Z<p>Chehri: Added an example SSH config.</p>
<hr />
<div>[[Category:Version Control System]]<br />
[[zh-CN:Git]]<br />
{{Related articles start}}<br />
{{Related|Super Quick Git Guide}}<br />
{{Related|Gitweb}}<br />
{{Related|Cgit}}<br />
{{Related|HTTP tunneling#Tunneling Git}}<br />
{{Related|Subversion}}<br />
{{Related|Concurrent Versions System}}<br />
{{Related articles end}}<br />
<br />
[[wikipedia:Git_%28software%29|Git]] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain sources for the Linux kernel as well as thousands of other projects, including a number of Arch Linux projects. <br />
<br />
== Installation ==<br />
<br />
[[Install]] {{Pkg|git}} from the [[official repositories]].<br />
<br />
If you want to use Git's built-in GUI tools (e.g. ''gitk'' or ''git gui''), make sure you have installed the {{Pkg|tk}} package, or they will refuse to start with a cryptic error:<br />
<br />
/usr/bin/gitk: line 3: exec: wish: not found.<br />
<br />
Also, the GUI tools require {{pkg|gsfonts}}, or they will crash with a segmentation fault.<br />
<br />
If you want to use the Git SVN bridge (''git svn'') you will need {{pkg|perl-term-readkey}}, or you will receive the following error: <br />
<br />
Can't locate Term/ReadKey.pm in @INC (you may need to install the Term::ReadKey module)<br />
<br />
== Basic configuration ==<br />
<br />
In order to use Git you need to set at least a name and email:<br />
<br />
$ git config --global user.name "''John Doe''"<br />
$ git config --global user.email "''johndoe@foobar.com''"<br />
<br />
See [[#Advanced configuration]] for more settings.<br />
<br />
== Basic usage ==<br />
<br />
This tutorial teaches how to use Git for basic distributed revision control of a project. A typical Git workflow is generally:<br />
<br />
# Create a new project or clone a remote one.<br />
# Create a branch to make changes; then commit those changes.<br />
# Consolidate commits for better organization/understanding.<br />
# Merge commits back into the main branch.<br />
# (Optional) Push changes to a remote server.<br />
<br />
=== Local repository ===<br />
<br />
==== Create a repository ====<br />
<br />
Initialize a new repository:<br />
<br />
$ git init<br />
<br />
Add files to the repository index:<br />
<br />
$ git add ''file1'' ''file2''<br />
<br />
Or, to add all files:<br />
<br />
$ git add .<br />
<br />
{{Tip|To use ''git add'' and have some files ignored, create a {{ic|.gitignore}} file:<br />
<br />
{{hc|.gitignore|<br />
# File I'll likely delete<br />
test-script<br />
}}<br />
}}<br />
<br />
Remove a file:<br />
<br />
$ git rm ''file''<br />
<br />
Rename a file:<br />
<br />
$ git mv ''file1'' ''file2''<br />
<br />
List files:<br />
<br />
$ git ls-files<br />
<br />
==== Commit changes ====<br />
<br />
In order to record the changes to the repository, they must first be added to the ''index'', or ''staging area'', with an operation often also referred to as ''staging''. This is done with the ''git add'' command:<br />
<br />
$ git add ''file''<br />
<br />
Once the content to be recorded is staged, it can be ''committed'' to the repository:<br />
<br />
$ git commit --message "First commit."<br />
<br />
The {{ic|--message}} option is for a short message: if omitted, the preset editor will be spawned to allow entering a longer message.<br />
<br />
{{Tip|<br />
* Always commit small changes frequently and with meaningful messages.<br />
* If you want to add all the modified files to the index, and commit them in a single command, do:<br />
<br />
$ git commit --all --message "First commit."<br />
}}<br />
<br />
To go back and edit the commit message:<br />
<br />
$ git commit --amend<br />
<br />
Many of the commands in this article take commits as arguments. A commit can be identified by any of the following:<br />
<br />
* Its 40-digit SHA-1 hash (the first 7 digits are usually sufficient to identify it uniquely)<br />
* Any commit label such as a branch or tag name<br />
* The label {{ic|HEAD}} always refers to the currently checked-out commit (usually the head of the branch, unless you used {{ic|git checkout}} to jump back in history to an old commit)<br />
* Any of the above plus {{ic|~}} to refer to previous commits. For example, {{ic|HEAD~}} refers to one commit before {{ic|HEAD}} and {{ic|HEAD~5}} refers to five commits before {{ic|HEAD}}.<br />
<br />
==== View changes ====<br />
<br />
Show differences between commits:<br />
<br />
$ git diff<br />
<br />
To get a general overview of the changes:<br />
<br />
$ git status<br />
<br />
View history of changes with:<br />
<br />
$ git log<br />
<br />
==== Branch a repository ====<br />
<br />
Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch. Branch names should reflect the alteration accurately:<br />
<br />
$ git branch help-section-addition<br />
<br />
To see the created branches:<br />
<br />
$ git branch<br />
<br />
To switch to a branch:<br />
<br />
$ git checkout ''branch''<br />
<br />
To create and switch to a branch in one step:<br />
<br />
$ git checkout -b ''branch''<br />
<br />
To merge a branch back to the master branch:<br />
<br />
$ git checkout master<br />
$ git merge ''branch''<br />
<br />
The changes will be merged if they do not conflict. If they do, the conflicts will be recorded. What is causing the conflicts can been seen with {{ic|git diff}}, then conflict resolution will need to be done manually.<br />
<br />
When done with a branch, it can be deleted by:<br />
<br />
$ git branch -d ''branch''<br />
<br />
=== Collaboration ===<br />
<br />
==== Adopting a good etiquette ====<br />
<br />
* When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.<br />
* Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the [[#History and versioning|log]] of the repository.<br />
* When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.<br />
* If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.<br />
<br />
==== Clone a repository ====<br />
<br />
To begin contributing to a project start by cloning its repository:<br />
<br />
$ git clone ''location'' ''folder''<br />
<br />
{{ic|''location''}} can be either a path or network address. Also, when cloning is done, the location is recorded so just a {{ic|git pull}} will be needed later.<br />
<br />
==== Pull requests ====<br />
<br />
After making and committing some changes, the contributor can ask the original author to the merge them; this is called a "pull request".<br />
<br />
The original author can merge the changes by doing:<br />
<br />
$ git pull ''location'' master<br />
<br />
The ''pull'' command fetches the changes and attempts to merge them. If there are conflicts (e.g. the original author made changes in the same time span) then it will be necessary to manually fix them.<br />
<br />
Alternatively, the original author can pick the changes wanting to be incorporated. Using the fetch option (and log option with a special {{ic|FETCH_HEAD}} symbol) the contents of the pull request can be viewed before deciding what to do:<br />
<br />
$ git fetch ''location'' master<br />
$ git log -p HEAD..FETCH_HEAD<br />
$ git merge ''location'' master<br />
<br />
==== Using remotes ====<br />
<br />
Remotes are tracked repositories, a {{ic|''label''}} defining a location. They are commonly used for frequently accessed repositories.<br />
<br />
$ git remote add ''label'' ''location''<br />
$ git fetch ''label''<br />
$ git log -p master..''label''/master<br />
<br />
Remotes for the current repository can be viewed with:<br />
<br />
$ git remote -v<br />
<br />
When defining a remote that is a parent of the fork (the project lead), it is defined as ''upstream''.<br />
<br />
==== Push to a repository ====<br />
<br />
If the contributor is given the rights from the original authors, the changes can be pushed:<br />
<br />
$ git push ''location'' ''branch''<br />
<br />
When {{ic|git clone}} is performed it records the original location and gives it a remote name of {{ic|origin}}. So what is typically done is this:<br />
<br />
$ git push origin master<br />
<br />
If the {{ic|--set-upstream}} option is used, the location is recorded so the next time just a {{ic|git push}} is necessary.<br />
<br />
==== Dealing with merges ====<br />
<br />
See [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts Basic Merge Conflicts] in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the {{ic|--abort}} command (e.g. {{ic|git merge --abort}} or {{ic|git pull --abort}}).<br />
<br />
=== History and versioning ===<br />
<br />
==== Searching the history ====<br />
<br />
{{ic|git log}} will give the history with a commit checksum, author, date, and the short message. To see the long message (the checksum can be truncated as long as it is unique):<br />
<br />
$ git show ''checksum''<br />
<br />
To show details of the last commit:<br />
<br />
$ git show HEAD<br />
<br />
To search through files of a previous commit it can be done with:<br />
<br />
$ git grep ''checksum''<br />
<br />
Ranges can also be specified:<br />
<br />
$ git grep ''tag2''..''tag4''<br />
<br />
==== Versioning for release ====<br />
<br />
For versioning, commits can be tagged:<br />
<br />
$ git tag 2.14 ''checksum''<br />
<br />
Tagging is generally done for [https://www.drupal.org/node/1066342 releasing/versioning] but it can be any string. Generally annotated tags are used because they get added to the Git database. To tag the current commit:<br />
<br />
$ git tag -a 2.14 -m "Version 2.14"<br />
<br />
Tags can be listed and deleted with:<br />
<br />
$ git tag -l<br />
$ git tag -d 2.08<br />
<br />
Tags that have to be updated remotely, have to be done so separately:<br />
<br />
$ git push --tags<br />
<br />
==== Organizing commits ====<br />
<br />
Before submitting a pull request it may be desirable to consolidate/organize the commits. This is done with the {{ic|git rebase}} interactive option:<br />
<br />
$ git rebase -i ''checksum''<br />
<br />
This will open the editor with a summary of all the commits in the range specified; in this case including the newest ({{ic|HEAD}}) to, but excluding, {{ic|''checksum''}}. Or to use a number notation, use for example {{ic|HEAD~3}}, which will rebase the last three commits.<br />
<br />
pick d146cc7 Mountpoint test.<br />
pick 4f47712 Explain -o option in readme.<br />
pick 8a4d479 Rename documentation.<br />
<br />
Editing the action in the first column will dictate how the rebase will be done. The options are:<br />
<br />
* {{ic|pick}} — Apply this commit as is (the default).<br />
* {{ic|edit}} — Edit files and/or commit message.<br />
* {{ic|reword}} — Edit commit message.<br />
* {{ic|squash}} — Merge/fold into previous commit.<br />
* {{ic|fixup}} — Merge/fold into previous commit discarding its message.<br />
<br />
The commits can be re-ordered or erased from the history (but be very careful with these). After editing the file, Git will perform the specified actions; if prompted to resolve merge problems, fix them and continue with {{ic|git rebase --continue}} or back out with the {{ic|git rebase --abort}} command.<br />
<br />
{{Note|Squashing commits is only used for local commits, it will cause troubles on a repository that is shared by other people.}}<br />
<br />
== Advanced configuration ==<br />
<br />
Git reads its configuration from a few INI-type configuration files:<br />
<br />
* Each repository contains a {{ic|.git/config}} file for specific configuration.<br />
* Each user has a {{ic|$HOME/.gitconfig}} file for fallback values.<br />
* {{ic|/etc/gitconfig}} is used for system-wide defaults.<br />
<br />
These files can be edited directly, but the usual method is to use the ''git-config'' utility as shown in the examples below.<br />
<br />
To list the currently set variables:<br />
<br />
$ git config {--local,--global,--system} --list<br />
<br />
The default editor is [[vim]] but to set it to [[nano]]:<br />
<br />
$ git config --global core.editor "nano -w"<br />
<br />
To set a default push action:<br />
<br />
$ git config --global push.default simple<br />
<br />
To set a tool for ''git difftool'' (by default it is ''meld''):<br />
<br />
$ git config --global diff.tool vimdiff<br />
<br />
See [https://www.kernel.org/pub/software/scm/git/docs/git-config.html git-config(1)] and [http://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration] for more information.<br />
<br />
=== Bash completion ===<br />
<br />
In order to enable Bash completion, source {{ic|/usr/share/git/completion/git-completion.bash}} in a [[Bash#Configuration_files|Bash startup file]]. Alternatively, install {{pkg|bash-completion}}.<br />
<br />
=== Git prompt ===<br />
<br />
The Git package comes with a prompt script. To enable it, source the {{ic|/usr/share/git/completion/git-prompt.sh}} script in a [[Autostarting#Shells|shell startup file]], then set a custom prompt with the {{ic|%s}} parameter:<br />
<br />
* For [[Bash]]: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}<br />
* For [[zsh]]: {{ic|1=PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}<br />
<br />
When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:<br />
<br />
{| class="wikitable"<br />
|+<br />
! Variable !! Information<br />
|-<br />
| GIT_PS1_SHOWDIRTYSTATE || '''+''' for staged, '''*''' if unstaged. <br />
|-<br />
| GIT_PS1_SHOWSTASHSTATE || '''$''' if something is stashed.<br />
|-<br />
| GIT_PS1_SHOWUNTRACKEDFILES || '''%''' if there are untracked files.<br />
|-<br />
| GIT_PS1_SHOWUPSTREAM || '''<,>,<>''' behind, ahead, or diverged from upstream.<br />
|}<br />
<br />
{{ic|GIT_PS1_SHOWUPSTREAM}} will need to be set to {{ic|auto}} for changes to take effect.<br />
<br />
{{Note|If you experience that {{ic|$(__git_ps1)}} returns {{ic|((unknown))}}, then there's a {{ic|.git}} folder in your current directory which does not contain any repository, and therefore Git does not recognize it. This can, for example, happen if you mistake Git's configuration file to be {{ic|~/.git/config}} instead of {{ic|~/.gitconfig}}.}}<br />
<br />
== Advanced usage ==<br />
<br />
To view get an idea of the amount of work done:<br />
<br />
$ git diff --stat<br />
<br />
Git log with forking representation:<br />
<br />
$ git log --graph --oneline --decorate<br />
<br />
Git log graph alias (i.e. {{ic|git graph}} will show the previous):<br />
<br />
$ git config --global alias.graph 'log --graph --oneline --decorate'<br />
<br />
Reset to previous commit (very dangerous, erases everything to specified commit):<br />
<br />
$ git reset --hard HEAD^<br />
<br />
If a repository address gets changed, its remote location will need to be updated:<br />
<br />
$ git remote set-url origin git@''address'':''user''/''repo''.git<br />
<br />
Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):<br />
<br />
$ git commit -s<br />
<br />
Signed-off-by automatically append to patches (when using {{ic|git format-patch ''commit''}}):<br />
<br />
$ git config --local format.signoff true<br />
<br />
Commit specific parts of files that have changed. This is useful if there are a large number of changes made that would be best split into several commits:<br />
<br />
$ git add -p<br />
<br />
=== Working with a non-master branch ===<br />
<br />
Occasionally a maintainer will ask that work be done on a branch. These branches are often called {{ic|devel}} or {{ic|testing}}. Begin by cloning the repository.<br />
<br />
To enter another branch beside master ({{ic|git clone}} only shows master branch but others still exist, {{ic|git branch -a}} to show):<br />
<br />
$ git checkout -b ''branch'' origin/''branch''<br />
<br />
Now edit normally; however to keep the repository tree in sync be sure to use both:<br />
<br />
$ git pull --all<br />
$ git push --all<br />
<br />
== Git server ==<br />
<br />
How to set up connecting to repositories using varying protocols.<br />
<br />
=== SSH ===<br />
<br />
To use the SSH protocol, first set up a public SSH key; for that follow the guide at [[SSH keys]]. To set up a SSH server, follow the [[SSH]] guide.<br />
<br />
With SSH working and a key generated, paste the contents of {{ic|~/.ssh/id_rsa.pub}} to {{ic|~/.ssh/authorized_keys}} (be sure it is all on one line). Now the Git repository can be accessed with SSH by doing:<br />
<br />
$ git clone user@foobar.com:repository-name.git<br />
<br />
You should now get an SSH yes/no question, if you have the SSH client setting {{ic|StrictHostKeyChecking}} set to {{ic|ask}} (the default). Type {{ic|yes}} followed by {{ic|Enter}}. Then you should have your repository checked out. Because this is with SSH, you also have commit rights now.<br />
<br />
To modify an existing repository to use SSH, the remote location will need to be redefined:<br />
<br />
$ git remote set-url origin git@localhost:my_repository.git<br />
<br />
Connecting on a port other than 22 can be configured on a per-host basis in {{ic|/etc/ssh/ssh_config}} or {{ic|~/.ssh/config}}. To set up ports for a repository, specify the path in {{ic|.git/config}}. It will have a format like this if the repository is in the home directory and is using 443 for the port:<br />
<br />
<nowiki>url = ssh://user@foobar.com:443/~repository-name/repo.git</nowiki><br />
<br />
==== Speeding up SSH ====<br />
<br />
Often if you find yourself pushing constantly to a few common servers, you may wish to remove the hassle of setting your username for each repository. <br />
<br />
If you don't already have the keys created, make them now.<br />
<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/aur -C "user@domain.com"<br />
$ ssh-keygen -N &rsquo;&rsquo; -b 4096 -t rsa -f ~/.ssh/github -C "user@domain.com"<br />
<br />
Add the resulting public keys to your accounts.<br />
<br />
Additionally, reusing the same SSH connection will drastically improve the time {{ic|git push}} takes.<br />
<br />
$ mkdir -p ~/.ssh/sockets/<br />
<br />
You may wish to adjust the {{ic|ServerAliveInterval}} depending on your connection.<br />
<br />
{{hc|~/.ssh/config|<br />
Host *<br />
ControlMaster auto<br />
ControlPath ~/.ssh/sockets/%r@%h-%p<br />
ControlPersist 8760h<br />
ServerAliveInterval 5<br />
ServerAliveCountMax 1<br />
TCPKeepAlive yes<br />
<br />
Host aur-dev.archlinux.org<br />
IdentityFile ~/.ssh/aur<br />
User aur<br />
Port 2222<br />
<br />
Host github.com<br />
IdentityFile ~/.ssh/github<br />
User [username here]<br />
}}<br />
<br />
=== Smart HTTP ===<br />
<br />
Git is able to use the HTTP(S) protocol as efficiently as the SSH or Git protocols, by utilizing the git-http-backend. Furthermore it is not only possible to clone or pull from repositories, but also to push into repositories over HTTP(S).<br />
<br />
The setup for this is rather simple as all you need to have installed is the Apache web server ({{pkg|apache}}, with {{ic|mod_cgi}}, {{ic|mod_alias}}, and {{ic|mod_env}} enabled) and of course, {{pkg|git}}.<br />
<br />
Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at {{ic|/etc/httpd/conf/httpd.conf}}:<br />
<Directory "/usr/lib/git-core*"><br />
Require all granted<br />
</Directory><br />
<br />
SetEnv GIT_PROJECT_ROOT /srv/git<br />
SetEnv GIT_HTTP_EXPORT_ALL<br />
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/<br />
<br />
The above example configuration assumes that your Git repositories are located at {{ic|/srv/git}} and that you want to access them via something like <nowiki>http(s)://your_address.tld/git/your_repo.git</nowiki>. Feel free to customize this to your needs.<br />
<br />
{{Note|Of course, you have to make sure that Apache can read and write (if you want to enable push access) to your Git repositories.}}<br />
<br />
For more detailed documentation, visit the following links:<br />
* http://progit.org/2010/03/04/smart-http.html<br />
* https://www.kernel.org/pub/software/scm/git/docs/v1.7.10.1/git-http-backend.html<br />
<br />
=== Git ===<br />
<br />
{{Note|The Git protocol only allows read access.}}<br />
<br />
[[start|Start and enable]] {{ic|git-daemon.socket}}.<br />
<br />
The daemon is started with the following options:<br />
<br />
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git<br />
<br />
Repositories placed in {{ic|/srv/git/}} will be recognized by the daemon. Clients can connect with something similar to:<br />
<br />
$ git clone git://''location''/''repository''.git<br />
<br />
=== Setting access rights ===<br />
<br />
To restrict read and/or write access, use standard Unix permissions. Refer to http://sitaramc.github.com/gitolite/doc/overkill.html{{Dead link|2013|11|06}} ([https://web.archive.org/web/20111004134500/http://sitaramc.github.com/gitolite/doc/overkill.html archive.org mirror]) for more information.<br />
<br />
For fine-grained access management, refer to [[gitolite]] and [[gitosis]].<br />
<br />
== See also ==<br />
<br />
* [http://git-scm.com/book Pro Git book]<br />
* [http://gitref.org/ Git Reference]<br />
* https://www.kernel.org/pub/software/scm/git/docs/<br />
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request Git overall]<br />
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git overall2]<br />
* https://wiki.videolan.org/Git<br />
* [https://gist.github.com/grawity/4392747 A comparison of protocols offered by GitHub]</div>Chehrihttps://wiki.archlinux.org/index.php?title=GnuPG&diff=338840GnuPG2014-10-05T17:01:18Z<p>Chehri: Rotating subkeys isn't needed as I've recently discovered, extending the expiry date is fine.</p>
<hr />
<div>[[ru:GnuPG]]<br />
[[Category:Security]]<br />
[http://www.gnupg.org GnuPG] allows to encrypt and sign your data and communication, features a versatile key management system as well as access modules for all kinds of public key directories.<br />
<br />
== Installation ==<br />
<br />
[[Install]] {{Pkg|gnupg}}, available in the [[official repositories]].<br />
<br />
This will also install {{Pkg|pinentry}}, a collection of simple PIN or passphrase entry dialogs which GnuPG uses for passphrase entry. ''pinentry'' is determined by the symbolic link {{ic|/usr/bin/pinentry}}, which by default points to {{ic|/usr/bin/pinentry-gtk-2}}.<br />
<br />
== Environment Variables ==<br />
<br />
=== GNUPGHOME ===<br />
<br />
{{ic|$GNUPGHOME}} is used by {{ic|GnuPGP}} to point to the directory where all configuration files are stored. By default {{ic|$GNUPGHOME}} isn't set and your {{ic|$HOME}} is used instead, thus you will find a {{ic|~/.gnupg}} directory right after the install. You may change this default setting by putting this line in one of your regular [[startup files]]<br />
export GNUPGHOME&#61;"/path/to/gnupg/directory"<br />
<br />
{{Note| By default, the gnupg directory has its [[Permissions]] set to ''700'' and the files it contains have their permissions set to ''600''. Only the owner of the directory has permission to read, write and execute (''r'',''w'',''x''). This is for security purposes and should not be changed. In case this directory or any file inside it does not follow this security measure, you will get warnings about unsafe file and home directory permissions.}}<br />
<br />
=== GPG_AGENT_INFO ===<br />
<br />
{{ic|GPG_AGENT_INFO}} used to locate the pgp-agent. Consists of 3 colon delimited fields:<br />
<br />
# path to Unix Domain Socket<br />
# PID of gpg-agent<br />
# protocol version set to 1<br />
<br />
E.g : {{ic|GPG_AGENT_INFO&#61;/tmp/gpg-eFqmSC/S.gpg-agent:7795:1}}. When starting the gpg-agent, this variable is set to the correct value.<br />
<br />
== Configuration file ==<br />
<br />
Default is {{ic|~/.gnupg/gpg.conf}}. If you want to change the default location, either run gpg this way {{ic|$ gpg --homedir ''path/to/file''}} or use {{ic|$GNUPGHOME}} variable.<br />
<br />
Append in this file any long options you want. Do not write the two dashes, but simply the name of the option and required arguments. You will find a skeleton file {{ic|usr/share/gnupg/gpg-conf.skel}}.<br />
Following is a basic configuration file:<br />
{{hc|~/.gnupg/gpg.conf|<br />
default-key ''name'' # useful in case you manage several keys and want to set a default one<br />
keyring ''file'' # will add ''file'' to the current list of keyrings<br />
trustdb-name ''file'' # use ''file'' instead of the default trustdb<br />
homedir ''dir'' # set the name of the gnupg home dir to ''dir'' instead of ~/.gnupg<br />
display-charset utf-8 # bypass all translation and assume that the OS uses native UTF-8 encoding<br />
keyserver ''name'' # use ''name'' as your keyserver<br />
no-greeting # suppress the initial copyright message<br />
armor # create ASCII armored output. Default is binary OpenPGP format<br />
}}<br />
<br />
If you want to set up default options for a multi-user system, the configuration file of defaults is expected in {{ic|/etc/skel/.gnupg/}}. With that in place the new user configuration can be created with<br />
# addgnupghome user1 user2<br />
which will add the respective {{ic|/home/userX/.gnupg/}} and copy the files from the skeleton directory to it.<br />
<br />
== Basic keys management ==<br />
<br />
{{Note|Whenever a ''{{ic|<user-id>}}'' is required in a command, it can be specified with your key ID, fingerprint, a part of your name or email address, etc. GnuPG is flexible on this.}}<br />
<br />
=== Create key ===<br />
<br />
* Set stronger algorithms to be used first:<br />
<br />
{{hc|~/.gnupg/gpg.conf|<br />
personal-digest-preferences SHA512<br />
cert-digest-algo SHA512<br />
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed<br />
personal-cipher-preferences TWOFISH CAMELLIA256 AES 3DES<br />
}}<br />
<br />
* Generate a private key by typing in a terminal:<br />
<br />
$ gpg --gen-key<br />
<br />
You will be asked several questions. In general, most users will want both a RSA (sign only) and a RSA (encrypt only) key. It is advised to use a keysize of 4096 bits (default is 2048).<br />
<br />
While having an expiration date for subkeys isn't technically necessary, it is considered good practice. A period of a year is generally good enough for the average user. This way even if you lose access to your keyring, it will allow others to know that it is no longer valid. Note that you can extend the expiry date after key creation without having to re-issue a new key.<br />
<br />
=== Manage your key ===<br />
<br />
* Running the {{ic|gpg --edit-key ''<user-id>''}} command will present a menu which enables you to do most of your key management related tasks. Following is an example to set your expiration date:<br />
<br />
$ gpg --edit-key ''<user-id>''<br />
> key ''number''<br />
> expire ''yyyy-mm-dd''<br />
> save<br />
> quit<br />
<br />
Some useful commands:<br />
> passwd # change the passphrase<br />
> clean # compact any user ID that is no longer usable (e.g revoked or expired)<br />
> revkey # revoke a key<br />
> addkey # add a subkey to this key<br />
> expire # change the key expiration time<br />
<br />
* Generate an ASCII version of your public key (e.g. to distribute it by e-mail):<br />
<br />
$ gpg --armor --output public.key --export ''<user-id>''<br />
<br />
* Register your key with a public PGP key server, so that others can retrieve your key without having to contact you directly:<br />
<br />
$ gpg --keyserver pgp.mit.edu --send-keys ''<user-id>''<br />
<br />
* Sign and encrypt for user Bob<br />
<br />
$ gpg -se -r Bob ''file''<br />
<br />
* make a clear text signature<br />
<br />
$ gpg --clearsign ''file''<br />
<br />
=== Rotating subkeys ===<br />
<br />
{{Warning|'''Never''' delete your expired or revoked subkeys unless you have a good reason. Doing so will cause you to lose the ability to decrypt files encrypted with the old subkey. Please '''only''' delete expired or revoked keys from other users to clean your keyring.}}<br />
<br />
If you have set your subkeys to expire after a set time, you can create new ones. Do this a few weeks in advanced to allow others to update their keyring.<br />
<br />
{{Note|You do not need to create a new key simply because it is expired. You can extend the expiration date.}}<br />
<br />
* Create new subkey (repeat for both signing and encrypting key)<br />
<br />
$ gpg --edit-key ''<user-id>''<br />
> addkey<br />
<br />
And answer the following questions it asks (see previous section for suggested settings).<br />
<br />
* Save changes<br />
<br />
> save<br />
<br />
* Update it to a keyserver.<br />
<br />
$ gpg --keyserver pgp.mit.edu --send-keys ''<user-id>''<br />
<br />
{{Note|Revoking expired subkeys is unnecessary and arguably bad form. If you are constantly revoking keys, it may cause others to lack confidence in you.}}<br />
<br />
=== Import key ===<br />
<br />
* Import a public key to your public key ring:<br />
<br />
$ gpg --import public.key<br />
<br />
* Import a private key to your secret key ring:<br />
<br />
$ gpg --import private.key<br />
<br />
=== List keys ===<br />
<br />
* Keys in your public key ring:<br />
<br />
$ gpg --list-keys<br />
<br />
* Keys in your secret key ring:<br />
<br />
$ gpg --list-secret-keys<br />
<br />
== Encrypt and decrypt ==<br />
<br />
When encrypting or decrypting it is possible to have more than one private key in use. If this occurs you need to select the active key. This can be done by using the option {{ic|-u UID}} or by using the option {{ic|--local-user UID}}. This causes the default key to use to be replaced by wanted key.<br />
<br />
To encrypt a file, use:<br />
<br />
$ gpg --encrypt -o secret.tar.gpg secret.tar<br />
<br />
* If you want to change recipient this can be done by the option {{ic|-r}} or by the option {{ic|--recipient}}.<br />
* You can use gnupg to encrypt your sensitive documents, but only individual files at a time. If you want to encrypt directories or a whole file-system you should consider using [[TrueCrypt]] or [[EncFS]], though you can always tarball various files and then encrypt them.<br />
<br />
To decrypt a file, use:<br />
<br />
$ gpg --decrypt secret.tar.gpg<br />
<br />
You'll be prompted to enter your passphrase.<br />
<br />
=== Encrypt a password ===<br />
<br />
It can be useful to encrypt some password, so it will not be written in clear on a configuration file. A good example is your email password.<br />
<br />
First create a file with your password. You '''need''' to leave '''one''' empty line after the password, otherwise gpg will return an error message when evaluating the file.<br />
<br />
Then run:<br />
<br />
$ gpg -e -a -r ''your_GPG_key_ID'' ''your_password_file''<br />
<br />
{{ic|-e}} is for encrypt, {{ic|-a}} for armor (ASCII output), {{ic|-r}} for recipient USER-ID.<br />
<br />
You will be left with a new {{ic|''your_password_file''.asc}} file.<br />
<br />
== gpg-agent ==<br />
<br />
{{Ic|Gpg-agent}} is mostly used as daemon to request and cache the password for the keychain. This is useful if GnuPG is used from an external program like a mail client. It can be activated by adding following line in {{ic|~/.gnupg/gpg.conf}}:<br />
use-agent<br />
<br />
This tells GnuPG to use the agent whenever it needs the password. However, the agent needs to run already. To autostart it, create the following file and make it executable, and remember to change the envfile path if you changed your $GNUPGHOME:<br />
<br />
{{hc|/etc/profile.d/gpg-agent.sh|2=<nowiki><br />
if [ $EUID -ne 0 ] ; then<br />
envfile="$HOME/.gnupg/gpg-agent.env"<br />
if [[ -e "$envfile" ]] && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then<br />
eval "$(cat "$envfile")"<br />
else<br />
eval "$(gpg-agent --daemon --enable-ssh-support --write-env-file "$envfile")"<br />
fi<br />
export GPG_AGENT_INFO # the env file does not contain the export statement<br />
export SSH_AUTH_SOCK # enable gpg-agent for ssh<br />
fi<br />
</nowiki>}}<br />
<br />
If you don't want gpg-agent to autostart for all users or just want to keep user daemons in the users own configuration files you can add the following entry to your {{Ic|.xinitrc}} or {{Ic|.bash_profile}}.<br />
<br />
eval $(gpg-agent --daemon)<br />
<br />
Log out of your Xsession and log back in. Check if {{Ic|gpg-agent}} is activated<br />
<br />
$ pgrep gpg-agent<br />
<br />
==== Configuration ====<br />
<br />
gpg-agent can be configured via {{ic|~/.gnupg/gpg-agent.conf}} file. The configuration options are listed in {{ic|man gpg-agent}}. For example you can change cache ttl for unused keys:<br />
<br />
{{hc|~/.gnupg/gpg-agent.conf|<br />
default-cache-ttl 3600<br />
}}<br />
<br />
==== Pinentry ====<br />
<br />
Finally, the agent needs to know how to ask the user for the password. This can be set in the gpg-agent configuration file.<br />
<br />
The default uses a gtk dialog. There are other options - see {{ic|info pinentry}}. To change the dialog implementation set {{ic|pinentry-program}} configuration option:<br />
{{hc|~/.gnupg/gpg-agent.conf|<br />
<br />
# PIN entry program<br />
# pinentry-program /usr/bin/pinentry-curses<br />
# pinentry-program /usr/bin/pinentry-qt4<br />
# pinentry-program /usr/bin/pinentry-kwallet<br />
<br />
pinentry-program /usr/bin/pinentry-gtk-2<br />
}}<br />
<br />
{{Tip|For using {{ic|/usr/bin/pinentry-kwallet}} you have to install the {{Pkg|kwalletcli}} package.}}<br />
<br />
== Keysigning Parties ==<br />
<br />
To allow users to validate keys on the keyservers and in their keyrings (i.e. make sure they are from whom they claim to be), PGP/GPG uses a so-called "Web of Trust". To build this Web of Trust, many hacker events include keysigning parties.<br />
<br />
The [https://en.wikipedia.org/wiki/Zimmermann%E2%80%93Sassaman_key-signing_protocol Zimmermann-Sassaman] key-signing protocol is a way of making these very effective. [http://www.cryptnet.net/fdp/crypto/keysigning_party/en/keysigning_party.html Here] you'll find a How-To-article.<br />
<br />
=== Caff ===<br />
<br />
For an easier process of signing keys and sending signatures to the owners after a keysigning party, you can use the tool 'caff'. It can be installed from the AUR with the package {{AUR|caff-svn}} or bundled together with other useful tools in the package {{AUR|signing-party-svn}}.<br />
Either way, there will be a lot of dependencies installing from the AUR. Alternatively you can install them with<br />
cpanm Any::Moose<br />
cpanm GnuPG::Interface<br />
<br />
To send the signatures to their owners you need a working [https://en.wikipedia.org/wiki/Message_transfer_agent MTA]. If you don't have already one, install [[msmtp]].<br />
<br />
== Smartcards ==<br />
<br />
{{Note|{{Pkg|pcsclite}} and {{Pkg|libusb-compat}} have to be installed, and the contained [[systemd#Using units|systemd]] service {{ic|pcscd.service}} has to be running.}}<br />
<br />
GnuPG uses ''scdaemon'' as an interface to your smartcard reader, please refer to the [[man page]] for details.<br />
<br />
=== GnuPG only setups ===<br />
<br />
If you do not plan to use other cards but those based on GnuPG, you should check the {{Ic|reader-port}} parameter in {{ic|~/.gnupg/scdaemon.conf}}. The value '0' refers to the first available serial port reader and a value of '32768' (default) refers to the first USB reader.<br />
<br />
=== GnuPG together with OpenSC ===<br />
<br />
If you are using any smartcard with an opensc driver (e.g.: ID cards from some countries) you should pay some attention to GnuPG configuration. Out of the box you might receive a message like this when using {{Ic|gpg --card-status}}<br />
<br />
gpg: selecting openpgp failed: ec=6.108<br />
<br />
By default, scdaemon will try to connect directly to the device. This connection will fail if the reader is being used by another process. For example: the pcscd daemon used by OpenSC. To cope with this situation we should use the same underlying driver as opensc so they can work well together. In order to point scdaemon to use pcscd you should remove {{Ic|reader-port}} from {{ic|~/gnupg/scdaemon.conf}}, specify the location to {{ic|libpcsclite.so}} library and disable ccid so we make sure that we use pcscd:<br />
<br />
{{hc|~/scdaemon.conf|<nowiki><br />
pcsc-driver /usr/lib/libpcsclite.so<br />
card-timeout 5<br />
disable-ccid<br />
</nowiki>}}<br />
<br />
Please check {{Ic|man scdaemon}} if you do not use OpenSC.<br />
<br />
== Troubleshooting ==<br />
<br />
=== Su ===<br />
<br />
When using {{Ic|pinentry}}, you must have the proper permisions of the terminal device (e.g. {{Ic|/dev/tty1}}) in use. However, with {{Ic|su}} (or {{Ic|sudo}}), the ownership stays with the original user, not the new one. This means that pinentry will fail, even as root. The fix is to change the permissions of the device at some point before the use of pinentry (i.e. using gpg with an agent). If doing gpg as root, simply change the ownership to root right before using gpg<br />
chown root /dev/ttyN # where N is the current tty<br />
and then change it back after using gpg the first time. The equivalent is likely to be true with {{Ic|/dev/pts/}}.<br />
<br />
{{Note|being part of the group {{Ic|tty}} '''does not''' seem to alleviate the issue, at least as root. (Please confirm with non-superusers)}}<br />
<br />
=== Agent complains end of file ===<br />
<br />
The default pinentry program is pinentry-gtk-2, which needs a DBus session bus to run properly. See [[General troubleshooting#Session permissions]] for details.<br />
<br />
Alternatively, you can use {{ic|pinentry-qt}}. See [[GnuPG#Pinentry]].<br />
<br />
=== KGpg configuration permissions ===<br />
<br />
There have been issues with {{Pkg|kdeutils-kgpg}} being able to access the {{ic|~/.gnupg/}} options. One issue might be a result of a deprecated ''options'' file, see the [https://bugs.kde.org/show_bug.cgi?id=290221 bug] report.<br />
<br />
Another user reported that ''KGpg'' failed to start until the {{ic|~/.gnupg}} folder is set to {{ic|drwxr-xr-x}} permissions. If you require this work-around, ensure that the directory contents retain {{ic|-rw-------}} permissions! Further, report it as a bug to the [https://bugs.kde.org/buglist.cgi?quicksearch=kgpg developers].<br />
<br />
=== Conflicts betweent gnome-keyring and GPG-Agent ===<br />
<br />
When using gnome-keyring for key storage, gpg issues the warning:<br />
gpg: WARNING: The GNOME keyring manager hijacked the GnuPG agent.<br />
gpg: WARNING: GnuPG will not work proberly - please configure that tool to not interfere with the GnuPG system<br />
<br />
Although some GPG Developers consider the behaviour of Gnome Keyring dangerous (see the [http://bugs.gnupg.org/gnupg/issue1656 issue report]), users that do not want to switch to the GPG-Agent can fix this temporarily by changing the AGENT_ID string in the binary of GPG2 to a command that gnome-keyring doesn't implement, say AGENX_ID:<br />
# sed -i s/AGENT_ID/AGENX_ID/ `which gpg2`<br />
<br />
== See also ==<br />
<br />
* [http://gnupg.org/gph/en/manual.html The GNU Privacy Handbook]<br />
* [http://blog.sanctum.geek.nz/series/linux-crypto/ A more comprehensive gpg Tutorial]<br />
* [https://www.gnupg.org/faq/gnupg-faq.html GnuPG FAQ]<br />
* [https://help.riseup.net/en/security/message-security/openpgp/gpg-best-practices gpg.conf recommendations and best practices]<br />
* [https://github.com/ioerror/torbirdy/blob/master/gpg.conf Torbirdy gpg.conf]</div>Chehrihttps://wiki.archlinux.org/index.php?title=Makepkg&diff=310220Makepkg2014-04-12T18:04:36Z<p>Chehri: /* Utilizing multiple cores on compression */</p>
<hr />
<div>[[Category:Package development]]<br />
[[Category:About Arch]]<br />
[[ar:Makepkg]]<br />
[[el:Makepkg]]<br />
[[es:Makepkg]]<br />
[[fr:makepkg]]<br />
[[it:Makepkg]]<br />
[[ja:Makepkg]]<br />
[[nl:Makepkg]]<br />
[[pt:Makepkg]]<br />
[[ru:Makepkg]]<br />
[[sr:Makepkg]]<br />
[[tr:Makepkg]]<br />
[[zh-CN:Makepkg]]<br />
{{Related articles start}}<br />
{{Related|Creating packages}}<br />
{{Related|PKGBUILD}}<br />
{{Related|Arch User Repository}}<br />
{{Related|pacman}}<br />
{{Related|Official repositories}}<br />
{{Related|Arch Build System}}<br />
{{Related articles end}}<br />
{{DISPLAYTITLE:makepkg}}<br />
makepkg is used for compiling and building packages suitable for installation with [[pacman]], Arch Linux's package manager. makepkg is a script that automates the building of packages; it can download and validate source files, check dependencies, configure build-time settings, compile the sources, install into a temporary root, make customizations, generate meta-info, and package everything together.<br />
<br />
makepkg is provided by the {{Pkg|pacman}} package.<br />
<br />
== Configuration ==<br />
{{ic|/etc/makepkg.conf}} is the main configuration file for makepkg. Most users will wish to fine-tune makepkg configuration options prior to building any packages. <br />
<br />
=== Architecture, compile flags ===<br />
The {{ic|MAKEFLAGS}}, {{ic|CFLAGS}}, and {{ic|CXXFLAGS}} options are used by {{Pkg|make}}, {{Pkg|gcc}}, and {{ic|g++}} whilst compiling software with makepkg. By default, these options generate generic packages that can be installed on a wide range of machines. A performance improvement can be achieved by tuning compilation for the host machine. The downside is that packages compiled specifically for the compiling host's processor may not run on other machines.<br />
<br />
{{Note|Do keep in mind that not all package build systems will use your exported variables. Some override them in the original Makefiles or the [[PKGBUILD]].}}<br />
<br />
{{hc|/etc/makepkg.conf|<nowiki><br />
[...]<br />
<br />
#########################################################################<br />
# ARCHITECTURE, COMPILE FLAGS<br />
#########################################################################<br />
#<br />
CARCH="x86_64"<br />
CHOST="x86_64-unknown-linux-gnu"<br />
<br />
#-- Exclusive: will only run on x86_64<br />
# -march (or -mcpu) builds exclusively for an architecture<br />
# -mtune optimizes for an architecture, but builds for whole processor family<br />
CPPFLAGS="-D_FORTIFY_SOURCE=2"<br />
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4"<br />
CXXFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4"<br />
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro"<br />
#-- Make Flags: change this for DistCC/SMP systems<br />
#MAKEFLAGS="-j2"<br />
<br />
[...]<br />
</nowiki>}}<br />
<br />
The default makepkg.conf {{ic|CFLAGS}} and {{ic|CXXFLAGS}} are compatible with all machines within their respective architectures. <br />
<br />
On x86_64 machines, there are rarely significant enough real world performance gains that would warrant investing the time to rebuild official packages.<br />
<br />
As of version 4.3.0, GCC offers the {{ic|1=-march=native}} switch that enables CPU auto-detection and automatically selects optimizations supported by the local machine at GCC runtime. To use it, just modify the default settings by changing the {{ic|CFLAGS}} and {{ic|CXXFLAGS}} lines as follows:<br />
<br />
# -march=native also sets the correct -mtune=<br />
CFLAGS="-march=native -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2"<br />
CXXFLAGS="${CFLAGS}"<br />
<br />
{{Tip|To see what {{ic|1=march=native}} flags are, run:<br />
<nowiki>$ gcc -march=native -E -v - </dev/null 2>&1 | sed -n 's/.* -v - //p'</nowiki><br />
}}<br />
<br />
Further optimizing for CPU type can theoretically enhance performance because {{ic|1=-march=native}} enables all available instruction sets and improves scheduling for a particular CPU. This is especially noticeable when rebuilding applications (for example: audio/video encoding tools, scientific applications, math-heavy programs, etc.) that can take heavy advantage of newer instructions sets not enabled when using the default options (or packages) provided by Arch Linux. <br />
<br />
It is very easy to reduce performance by using "non-standard" CFLAGS because compilers tend to heavily blow up the code size with loop unrolling, bad vectorization, crazy inlining, etc. depending on compiler switches. Unless you can verify/benchmark that something is faster, there is a very good chance it is not! <br />
<br />
See the GCC man page for a complete list of available options. The Gentoo [http://www.gentoo.org/doc/en/gcc-optimization.xml Compilation Optimization Guide] and [http://wiki.gentoo.org/wiki/Safe_CFLAGS Safe CFLAGS] wiki article provide more in-depth information.<br />
<br />
====MAKEFLAGS====<br />
The {{ic|MAKEFLAGS}} option can be used to specify additional options for make. Users with multi-core/multi-processor systems can specify the number of jobs to run simultaneously. This can be accomplished with the use of {{ic|nproc}} to determine the number of available processors, e.g. {{ic|-j4}} ''(where 4 is the output of {{ic|nproc}})''. Some [[PKGBUILD]]'s specifically override this with {{ic|-j1}}, because of race conditions in certain versions or simply because it is not supported in the first place. Packages that fail to build because of this should be [[Reporting Bug Guidelines|reported]] on the bug tracker after making sure that the error is indeed being caused by your MAKEFLAGS.<br />
<br />
See {{ic|man make}} for a complete list of available options.<br />
<br />
=== Package output ===<br />
Next, one can configure where source files and packages should be placed and identify themselves as the packager. This step is optional; packages will be created in the working directory where makepkg is run by default.<br />
<br />
{{hc|/etc/makepkg.conf|<nowiki><br />
[...]<br />
<br />
#########################################################################<br />
# PACKAGE OUTPUT<br />
#########################################################################<br />
#<br />
# Default: put built package and cached source in build directory<br />
#<br />
#-- Destination: specify a fixed directory where all packages will be placed<br />
#PKGDEST=/home/packages<br />
#-- Source cache: specify a fixed directory where source files will be cached<br />
#SRCDEST=/home/sources<br />
#-- Source packages: specify a fixed directory where all src packages will be placed<br />
#SRCPKGDEST=/home/srcpackages<br />
#-- Packager: name/email of the person or organization building packages<br />
#PACKAGER="John Doe <john@doe.com>"<br />
<br />
[...]<br />
</nowiki>}}<br />
<br />
For example, create the directory:<br />
<br />
$ mkdir /home/$USER/packages<br />
<br />
Then modify the {{ic|PKGDEST}} variable in {{ic|/etc/makepkg.conf}} accordingly.<br />
<br />
The {{ic|PACKAGER}} variable will set the {{ic|packager}} value within compiled packages' {{ic|.PKGINFO}} metadata file. By default, user-compiled packages will display:<br />
<br />
{{hc|pacman -Qi package|<nowiki><br />
[...]<br />
Packager : Unknown Packager<br />
[...]<br />
</nowiki>}}<br />
<br />
Afterwards:<br />
<br />
{{hc|pacman -Qi package|<nowiki><br />
[...]<br />
Packager : John Doe <john@doe.com><br />
[...]<br />
</nowiki>}}<br />
<br />
This is useful if multiple users will be compiling packages on a system, or you are otherwise distributing your packages to other users.<br />
<br />
=== Signature checking ===<br />
The following procedure is not necessary for compiling with makepkg, for your initial configuration proceed to [[#Usage]]. To temporarily disable signature checking, call the makepkg command with the {{ic|--skippgpcheck}} option.<br />
If a signature file in the form of .sig is part of the [[PKGBUILD]] source array, makepkg validates the authenticity of source files. For example, the signature {{ic|pkgname-pkgver.tar.gz.sig}} is used to check the integrity of the file {{ic|pkgname-pkgver.tar.gz}} with the gpg program. If desired, signatures by other developers can be manually added to the GPG keyring. Look into the [[GnuPG]] article for further information.<br />
<br />
{{Note|The signature checking implemented in makepkg does not use pacman's keyring. Configure GPG, as explained below, to allow makepkg to read pacman's keyring.}}<br />
<br />
The GPG keys are expected to be stored in the user's {{ic|~/.gnupg/pubring.gpg}} file. In case it does not contain the given signature, makepkg shows a warning.<br />
{{hc|makepkg|<nowiki><br />
[...]<br />
==> Verifying source file signatures with gpg...<br />
pkgname-pkgver.tar.gz ... FAILED (unknown public key 1234567890)<br />
==> WARNING: Warnings have occurred while verifying the signatures.<br />
Please make sure you really trust them.<br />
[...]<br />
</nowiki>}}<br />
To show the current list of GPG keys, use the gpg command.<br />
{{bc|gpg --list-keys}}<br />
If the {{ic|pubring.gpg}} file does not exist, it will be created for you immediately.<br />
You can now proceed with configuring gpg to allow compiling AUR packages submitted by Arch Linux developers with successful signature checking.<br />
Add the following line to the end of your GPG configuration file to include the pacman keyring in your user's personal keyring.<br />
{{hc|~/.gnupg/gpg.conf|<nowiki><br />
[...]<br />
keyring /etc/pacman.d/gnupg/pubring.gpg<br />
</nowiki>}}<br />
When configured as before, the output of {{ic|gpg --list-keys}} contains a list of keyrings and developers. Now makepkg can compile AUR packages submitted by Arch Linux developers with successful signature checking.<br />
<br />
== Usage ==<br />
Before continuing, ensure the {{Grp|base-devel}} group is installed. Packages belonging to this group are not required to be listed as dependencies in [[PKGBUILD]] files. Install the "base-devel" group by issuing (as root):<br />
<br />
# pacman -S base-devel<br />
<br />
{{Note|Before complaining about missing (make) dependencies, remember that the {{Grp|base}} group is assumed to be installed on all Arch Linux systems. The group "base-devel" is assumed to be installed when building with ''makepkg'' or when using [[AUR helpers]].}}<br />
<br />
To build a package, one must first create a [[PKGBUILD]], or build script, as described in [[Creating packages]], or obtain one from the [[Arch Build System|ABS tree]], [[Arch User Repository]], or some other source. <br />
<br />
{{Warning|Only build and/or install packages from trusted sources.}}<br />
<br />
Once in possession of a {{ic|PKGBUILD}}, change to the directory where it is saved and issue the following command to build the package described by said {{ic|PKGBUILD}}:<br />
<br />
$ makepkg<br />
<br />
To have makepkg clean out leftover files and folders, such as files extracted to the $srcdir, add the following option. This is useful for multiple builds of the same package or updating the package version, while using the same build folder. It prevents obsolete and remnant files from carrying over to the new builds.<br />
<br />
$ makepkg -c<br />
<br />
If required dependencies are missing, makepkg will issue a warning before failing. To build the package and install needed dependencies automatically, simply use the command:<br />
<br />
$ makepkg -s<br />
<br />
Note that these dependencies must be available in the configured repositories; see [[pacman#Repositories]] for details. Alternatively, one can manually install dependencies prior to building ({{ic|pacman -S --asdeps dep1 dep2}}).<br />
<br />
Once all dependencies are satisfied and the package builds successfully, a package file ({{ic|pkgname-pkgver.pkg.tar.xz}}) will be created in the working directory. To install, run (as root):<br />
<br />
# pacman -U pkgname-pkgver.pkg.tar.xz<br />
<br />
Alternatively, to install, using the {{ic|-i}} flag is an easier way of running {{ic|pacman -U pkgname-pkgver.pkg.tar.xz}}, as in:<br />
<br />
$ makepkg -i<br />
<br />
== Tips and Tricks ==<br />
=== Improving compile times ===<br />
As an I/O intensive task, the use of a [[tmpfs]] for compiling packages may bring significant improvements in build times. Relevant option in {{ic|/etc/makepkg.conf}} is to be found at the end of the {{ic|BUILD ENVIRONMENT}} section:<br />
{{hc|/etc/makepkg.conf|<nowiki><br />
[...]<br />
<br />
#########################################################################<br />
# BUILD ENVIRONMENT<br />
#########################################################################<br />
#<br />
# Defaults: BUILDENV=(fakeroot !distcc color !ccache check !sign)<br />
# A negated environment option will do the opposite of the comments below.<br />
#<br />
#-- fakeroot: Allow building packages as a non-root user<br />
#-- distcc: Use the Distributed C/C++/ObjC compiler<br />
#-- color: Colorize output messages<br />
#-- ccache: Use ccache to cache compilation<br />
#-- check: Run the check() function if present in the PKGBUILD<br />
#-- sign: Generate PGP signature file<br />
#<br />
BUILDENV=(fakeroot !distcc color !ccache check !sign)<br />
#<br />
#-- If using DistCC, your MAKEFLAGS will also need modification. In addition,<br />
#-- specify a space-delimited list of hosts running in the DistCC cluster.<br />
#DISTCC_HOSTS=""<br />
#<br />
#-- Specify a directory for package building.<br />
#BUILDDIR=/tmp<br />
<br />
[...]<br />
</nowiki>}}<br />
<br />
Uncommenting the {{ic|1=BUILDDIR=/tmp}} line and setting it to e.g. {{ic|1=BUILDDIR=/tmp/builds}} (or leaving it to its default value) will make use of Arch default {{ic|/tmp}} [[tmpfs]].<br />
{{Note|The [[tmpfs]] folder needs to be mounted without the {{ic|noexec}} option, else it will prevent build scripts or utilities from being executed. Also, as stated in [[fstab#tmpfs]], its default size is half of the available RAM so you may run out of space.}}<br />
Please be reminded that any package compiled in [[tmpfs]] will not persist across reboot. Therefore, such packages should be installed consecutively to building or be moved to another (persistent) directory.<br />
<br />
=== Generate new checksums ===<br />
Since [http://allanmcrae.com/2013/04/pacman-4-1-released/ pacman 4.1], {{ic|makepkg -g >> PKGBUILD}} is no longer required because pacman-contrib was [https://projects.archlinux.org/pacman.git/tree/NEWS merged into upstream pacman], including the {{ic|updpkgsums}} script that will generate new checksums and/or replace them in the PKGBUILD. In the same directory as the PKGBUILD file, run the following command:<br />
$ updpkgsums<br />
<br />
=== Makepkg source PKGBUILD twice ===<br />
Makepkg sources the PKGBUILD twice (once when initially run, and the second time under fakeroot). Any non-standard functions placed in the PKGBUILD will be run twice as well.<br />
<br />
=== WARNING: Package contains reference to $srcdir ===<br />
Somehow, the literal strings {{ic|$srcdir}} or {{ic|$pkgdir}} ended up in one of the installed files in your package.<br />
<br />
To identify which files, run the following from the makepkg build directory:<br />
$ grep -R "$(pwd)/src" pkg/<br />
<br />
[http://www.mail-archive.com/arch-general@archlinux.org/msg15561.html Link] to discussion thread.<br />
<br />
=== Create uncompressed packages ===<br />
If you only want to install packages locally, you can speed up the process by avoiding the [[Wikipedia:xz|LZMA2]] compression and subsequent decompression:<br />
<br />
{{hc|/etc/makepkg.conf|2=<br />
[...]<br />
#PKGEXT='.pkg.tar.xz'<br />
PKGEXT='.pkg.tar'<br />
[...]<br />
}}<br />
<br />
=== Utilizing multiple cores on compression ===<br />
{{pkg|xz}} does not yet support [[Wikipedia:Symmetric multiprocessing|symmetric multiprocessing (SMP)]] on compression. This can be done with {{Pkg|p7zip}}:<br />
<br />
{{hc|/etc/makepkg.conf|2=<br />
[...]<br />
COMPRESSXZ=(7z a dummy -txz -si -so)<br />
[...]<br />
}}<br />
<br />
[https://aur.archlinux.org/packages/xz-git/ xz-git] from the AUR now supports [[Wikipedia:Symmetric multiprocessing|symmetric multiprocessing (SMP)]].<br />
<br />
{{hc|/etc/makepkg.conf|2=<br />
[...]<br />
COMPRESSXZ=(xz -T0 -c -z -)<br />
[...]<br />
}}<br />
<br />
== See also ==<br />
* [https://www.archlinux.org/pacman/makepkg.8.html makepkg(8) Manual Page]<br />
* [https://www.archlinux.org/pacman/makepkg.conf.5.html makepkg.conf(5) Manual Page]<br />
* [https://github.com/pixelb/scripts/blob/master/scripts/gcccpuopt gcccpuopt]: A script to print the GCC CPU-specific options tailored for the current CPU</div>Chehrihttps://wiki.archlinux.org/index.php?title=Change_username&diff=308137Change username2014-04-04T06:41:50Z<p>Chehri: /* Procedure */</p>
<hr />
<div>[[Category:Security]]<br />
[[es:Change username]]<br />
[[zh-CN:Change username]]<br />
{{Related articles start}}<br />
{{Related|Users and groups}}<br />
{{Related articles end}}<br />
Changing a username under Arch (or any flavor of Linux) is safe and easy when done properly. You can also change the associated groupname for the user if you wish. Following the procedure below will do just this retaining your UID/GID for the affected user thus not roaching any file permissions you have setup.<br />
<br />
==Procedure==<br />
{{Warning|Make certain that you are not logged in as the user whose name you are about to change! Open a new tty ({{ic|Ctrl}}+{{ic|Alt}}+{{ic|F1}}) and log in as root or as another user and su to root. usermod should prevent you from doing this by mistake.}}<br />
<br />
===Change A User's Login===<br />
This will change only the user's login name.<br />
# usermod -l newname oldname<br />
<br />
===Change the Real Name===<br />
This will change the real name of the username.<br />
# usermod -c "New Real Name" username<br />
<br />
===Change A User's $HOME===<br />
This will only change the home directory of '''username'''<br />
# usermod -d /my/new/home username<br />
<br />
===Change A User's $HOME and Move Contents===<br />
This will move the contents of '''username''''s home directory to {{ic|/my/new/home}} and set the user's home directory to the new one.<br />
# usermod -md /my/new/home username<br />
<br />
===Link A User's former $HOME to new $HOME===<br />
This will created a link between '''username''''s former home directory to the new one. Doing this will allow programs to find files that have hardcoded paths.<br />
{{Warning|Make sure there is no trailing / on {{ic|/my/old/home}}}}<br />
# ln -s /my/new/home/ /my/old/home<br />
<br />
===Change Group Name===<br />
If you want to change the user's group also:<br />
# groupmod -n newname oldname<br />
<br />
{{Note|This will change a group name but not the numerical GID of the group.}}<br />
<br />
For further information see the man pages for usermod and groupmod.<br />
<br />
===Manually With /etc/passwd===<br />
When possible, you should use the above commands to modify usernames and home directories, however for those of you who want to know the 'guts' of the operations, it can be done manually.<br />
<br />
====/etc/passwd File Format====<br />
Each line of the file follows a specific format. There are seven fields, each delimited by (":") a colon.<br />
<pre><br />
<login name>:<password>:<numerical UID>:<numerical GID>:<Real name/comments>:<home directory>:<user command interpreter><br />
</pre><br />
<br />
{{Warning|It is unsafe to set the <password> field in {{ic|/etc/passwd}}. Passwords should be changed (by root) with the '''passwd''' command!}}<br />
* <login name> This field can not be blank. Standard *NIX naming rules apply.<br />
* <password> would be an encrypted password, however it should be marked with a lowercase "x" (without quotes) to signify the password is located in {{ic|/etc/shadow}}.<br />
* Each user and group name has a corresponding numerical UID and GID (User ID and Group ID). In Arch, the first login name (after root) is UID 1000 by default. Subsequent UID/GID entries for users should be greater than 1000. GID should match the primary group for the particular user. Numeric values for GIDs are listed in {{ic|/etc/group}}.<br />
* <Real name/comments> is used by services such as '''finger'''. This field is optional and may be left blank.<br />
* <home directory> is used by the login command to set the {{Ic|$HOME}} environment variable. Several services with their own users use "/" which is safe for services, but not recommended for normal users.<br />
* <user command interpreter> is the path to the user's default shell. This is normally [[Bash]], but there are several other command line interpreters available. The default setting is "/bin/bash" (without quotes) for users. If you use another CLI, set the path to it here. This field is optional.<br />
<br />
Example (user):<br />
jack:x:1001:100:Jack Smith,some comment here,,:/home/jack:/bin/bash<br />
<br />
Broken down, this means: user jack (who's password is in {{ic|/etc/shadow}}) is UID 1001 and his primary group is 100 (users). Jack Smith is his full name and there is a comment associated to his account. His home directory is {{ic|/home/jack}} and he is using Bash.<br />
<br />
==Gotchas==<br />
*If you are using [[sudo]] make sure you update your {{ic|/etc/sudoers}} to reflect the new username(s) (via the visudo command as root).<br />
*If you modified your PATH statement in your {{ic|~/.bashrc}}, make sure you change it to reflect the new username.<br />
*Likewise, be sure you change any config file such as {{ic|/etc/rc.local}} or whatever if you are pointing it to a script or mountpoint, etc. within the old user's home directory.<br />
*Personal [[cron#Crontab_format|crontabs]] need to be adjusted by renaming the user's file in {{ic|/var/spool/cron}} from the old to the new name, and then opening {{ic|crontab -e}} to change any relevant paths and have it adjust the file permissions accordingly.<br />
* [[Wine|Wine's]] personal folders/files' contents in {{ic|~/.wine/drive_c/users}}, {{ic|~/.local/share/applications/wine/Programs}} and possibly more need to be manually renamed/edited. <br />
*The procedure to [[Firefox#Enable_spell_checking|enable spell checking]] in Firefox may need to be redone, or else the check-as-you-type spelling might not work after renaming the user.<br />
*Certain Thunderbird addons, like [http://enigmail.mozdev.org/home/index.php Enigmail], may need to be reinstalled.<br />
*Anything on your system (desktop shortcuts, shell scripts, etc.) that uses an absolute path to your home dir (i.e. {{ic|/home/oldname}}) will need to be changed to reflect your new name. To avoid these problems in shell scripts, simply use the {{Ic|~}} or {{Ic|$HOME}} variables for home directories.<br />
*Also don't forget to edit accordingly the configuration files in {{ic|/etc}} that relies on your absolute path (i.e. Samba, CUPS, so on). A nice way to learn what files you need to update involves using the grep command this way: {{ic|# grep -r {old_user} *}}</div>Chehrihttps://wiki.archlinux.org/index.php?title=Change_username&diff=308135Change username2014-04-04T06:38:52Z<p>Chehri: No need for that extra ;</p>
<hr />
<div>[[Category:Security]]<br />
[[es:Change username]]<br />
[[zh-CN:Change username]]<br />
{{Related articles start}}<br />
{{Related|Users and groups}}<br />
{{Related articles end}}<br />
Changing a username under Arch (or any flavor of Linux) is safe and easy when done properly. You can also change the associated groupname for the user if you wish. Following the procedure below will do just this retaining your UID/GID for the affected user thus not roaching any file permissions you have setup.<br />
<br />
==Procedure==<br />
{{Warning|Make certain that you are not logged in as the user whose name you are about to change! Open a new tty ({{ic|Ctrl}}+{{ic|Alt}}+{{ic|F1}}) and log in as root or as another user and su to root.}}<br />
<br />
===Change A User's Login===<br />
This will change only the user's login name.<br />
# usermod -l newname oldname<br />
<br />
===Change the Real Name===<br />
This will change the real name of the username.<br />
# usermod -c "New Real Name" username<br />
<br />
===Change A User's $HOME===<br />
This will only change the home directory of '''username'''<br />
# usermod -d /my/new/home username<br />
<br />
===Change A User's $HOME and Move Contents===<br />
This will move the contents of '''username''''s home directory to {{ic|/my/new/home}} and set the user's home directory to the new one.<br />
# usermod -md /my/new/home username<br />
<br />
===Link A User's former $HOME to new $HOME===<br />
This will created a link between '''username''''s former home directory to the new one. Doing this will allow programs to find files that have hardcoded paths.<br />
{{Warning|Make sure there is no trailing / on {{ic|/my/old/home}}}}<br />
# ln -s /my/new/home/ /my/old/home<br />
<br />
===Change Group Name===<br />
If you want to change the user's group also:<br />
# groupmod -n newname oldname<br />
<br />
{{Note|This will change a group name but not the numerical GID of the group.}}<br />
<br />
For further information see the man pages for usermod and groupmod.<br />
<br />
===Manually With /etc/passwd===<br />
When possible, you should use the above commands to modify usernames and home directories, however for those of you who want to know the 'guts' of the operations, it can be done manually.<br />
<br />
====/etc/passwd File Format====<br />
Each line of the file follows a specific format. There are seven fields, each delimited by (":") a colon.<br />
<pre><br />
<login name>:<password>:<numerical UID>:<numerical GID>:<Real name/comments>:<home directory>:<user command interpreter><br />
</pre><br />
<br />
{{Warning|It is unsafe to set the <password> field in {{ic|/etc/passwd}}. Passwords should be changed (by root) with the '''passwd''' command!}}<br />
* <login name> This field can not be blank. Standard *NIX naming rules apply.<br />
* <password> would be an encrypted password, however it should be marked with a lowercase "x" (without quotes) to signify the password is located in {{ic|/etc/shadow}}.<br />
* Each user and group name has a corresponding numerical UID and GID (User ID and Group ID). In Arch, the first login name (after root) is UID 1000 by default. Subsequent UID/GID entries for users should be greater than 1000. GID should match the primary group for the particular user. Numeric values for GIDs are listed in {{ic|/etc/group}}.<br />
* <Real name/comments> is used by services such as '''finger'''. This field is optional and may be left blank.<br />
* <home directory> is used by the login command to set the {{Ic|$HOME}} environment variable. Several services with their own users use "/" which is safe for services, but not recommended for normal users.<br />
* <user command interpreter> is the path to the user's default shell. This is normally [[Bash]], but there are several other command line interpreters available. The default setting is "/bin/bash" (without quotes) for users. If you use another CLI, set the path to it here. This field is optional.<br />
<br />
Example (user):<br />
jack:x:1001:100:Jack Smith,some comment here,,:/home/jack:/bin/bash<br />
<br />
Broken down, this means: user jack (who's password is in {{ic|/etc/shadow}}) is UID 1001 and his primary group is 100 (users). Jack Smith is his full name and there is a comment associated to his account. His home directory is {{ic|/home/jack}} and he is using Bash.<br />
<br />
==Gotchas==<br />
*If you are using [[sudo]] make sure you update your {{ic|/etc/sudoers}} to reflect the new username(s) (via the visudo command as root).<br />
*If you modified your PATH statement in your {{ic|~/.bashrc}}, make sure you change it to reflect the new username.<br />
*Likewise, be sure you change any config file such as {{ic|/etc/rc.local}} or whatever if you are pointing it to a script or mountpoint, etc. within the old user's home directory.<br />
*Personal [[cron#Crontab_format|crontabs]] need to be adjusted by renaming the user's file in {{ic|/var/spool/cron}} from the old to the new name, and then opening {{ic|crontab -e}} to change any relevant paths and have it adjust the file permissions accordingly.<br />
* [[Wine|Wine's]] personal folders/files' contents in {{ic|~/.wine/drive_c/users}}, {{ic|~/.local/share/applications/wine/Programs}} and possibly more need to be manually renamed/edited. <br />
*The procedure to [[Firefox#Enable_spell_checking|enable spell checking]] in Firefox may need to be redone, or else the check-as-you-type spelling might not work after renaming the user.<br />
*Certain Thunderbird addons, like [http://enigmail.mozdev.org/home/index.php Enigmail], may need to be reinstalled.<br />
*Anything on your system (desktop shortcuts, shell scripts, etc.) that uses an absolute path to your home dir (i.e. {{ic|/home/oldname}}) will need to be changed to reflect your new name. To avoid these problems in shell scripts, simply use the {{Ic|~}} or {{Ic|$HOME}} variables for home directories.<br />
*Also don't forget to edit accordingly the configuration files in {{ic|/etc}} that relies on your absolute path (i.e. Samba, CUPS, so on). A nice way to learn what files you need to update involves using the grep command this way: {{ic|# grep -r {old_user} *}}</div>Chehrihttps://wiki.archlinux.org/index.php?title=Change_username&diff=308134Change username2014-04-04T06:35:16Z<p>Chehri: Added directions for creating a softlink between a user's current and former home.</p>
<hr />
<div>[[Category:Security]]<br />
[[es:Change username]]<br />
[[zh-CN:Change username]]<br />
{{Related articles start}}<br />
{{Related|Users and groups}}<br />
{{Related articles end}}<br />
Changing a username under Arch (or any flavor of Linux) is safe and easy when done properly. You can also change the associated groupname for the user if you wish. Following the procedure below will do just this retaining your UID/GID for the affected user thus not roaching any file permissions you have setup.<br />
<br />
==Procedure==<br />
{{Warning|Make certain that you are not logged in as the user whose name you are about to change! Open a new tty ({{ic|Ctrl}}+{{ic|Alt}}+{{ic|F1}}) and log in as root or as another user and su to root.}}<br />
<br />
===Change A User's Login===<br />
This will change only the user's login name.<br />
# usermod -l newname oldname<br />
<br />
===Change the Real Name===<br />
This will change the real name of the username.<br />
# usermod -c "New Real Name" username<br />
<br />
===Change A User's $HOME===<br />
This will only change the home directory of '''username'''<br />
# usermod -d /my/new/home username<br />
<br />
===Change A User's $HOME and Move Contents===<br />
This will move the contents of '''username''''s home directory to {{ic|/my/new/home}} and set the user's home directory to the new one.<br />
# usermod -md /my/new/home username;<br />
<br />
===Link A User's former $HOME to new $HOME===<br />
This will created a link between '''username''''s former home directory to the new one. Doing this will allow programs to find files that have hardcoded paths.<br />
{{Warning|Make sure there is no trailing / on {{ic|/my/old/home}}}}<br />
# ln -s /my/new/home/ /my/old/home<br />
<br />
===Change Group Name===<br />
If you want to change the user's group also:<br />
# groupmod -n newname oldname<br />
<br />
{{Note|This will change a group name but not the numerical GID of the group.}}<br />
<br />
For further information see the man pages for usermod and groupmod.<br />
<br />
===Manually With /etc/passwd===<br />
When possible, you should use the above commands to modify usernames and home directories, however for those of you who want to know the 'guts' of the operations, it can be done manually.<br />
<br />
====/etc/passwd File Format====<br />
Each line of the file follows a specific format. There are seven fields, each delimited by (":") a colon.<br />
<pre><br />
<login name>:<password>:<numerical UID>:<numerical GID>:<Real name/comments>:<home directory>:<user command interpreter><br />
</pre><br />
<br />
{{Warning|It is unsafe to set the <password> field in {{ic|/etc/passwd}}. Passwords should be changed (by root) with the '''passwd''' command!}}<br />
* <login name> This field can not be blank. Standard *NIX naming rules apply.<br />
* <password> would be an encrypted password, however it should be marked with a lowercase "x" (without quotes) to signify the password is located in {{ic|/etc/shadow}}.<br />
* Each user and group name has a corresponding numerical UID and GID (User ID and Group ID). In Arch, the first login name (after root) is UID 1000 by default. Subsequent UID/GID entries for users should be greater than 1000. GID should match the primary group for the particular user. Numeric values for GIDs are listed in {{ic|/etc/group}}.<br />
* <Real name/comments> is used by services such as '''finger'''. This field is optional and may be left blank.<br />
* <home directory> is used by the login command to set the {{Ic|$HOME}} environment variable. Several services with their own users use "/" which is safe for services, but not recommended for normal users.<br />
* <user command interpreter> is the path to the user's default shell. This is normally [[Bash]], but there are several other command line interpreters available. The default setting is "/bin/bash" (without quotes) for users. If you use another CLI, set the path to it here. This field is optional.<br />
<br />
Example (user):<br />
jack:x:1001:100:Jack Smith,some comment here,,:/home/jack:/bin/bash<br />
<br />
Broken down, this means: user jack (who's password is in {{ic|/etc/shadow}}) is UID 1001 and his primary group is 100 (users). Jack Smith is his full name and there is a comment associated to his account. His home directory is {{ic|/home/jack}} and he is using Bash.<br />
<br />
==Gotchas==<br />
*If you are using [[sudo]] make sure you update your {{ic|/etc/sudoers}} to reflect the new username(s) (via the visudo command as root).<br />
*If you modified your PATH statement in your {{ic|~/.bashrc}}, make sure you change it to reflect the new username.<br />
*Likewise, be sure you change any config file such as {{ic|/etc/rc.local}} or whatever if you are pointing it to a script or mountpoint, etc. within the old user's home directory.<br />
*Personal [[cron#Crontab_format|crontabs]] need to be adjusted by renaming the user's file in {{ic|/var/spool/cron}} from the old to the new name, and then opening {{ic|crontab -e}} to change any relevant paths and have it adjust the file permissions accordingly.<br />
* [[Wine|Wine's]] personal folders/files' contents in {{ic|~/.wine/drive_c/users}}, {{ic|~/.local/share/applications/wine/Programs}} and possibly more need to be manually renamed/edited. <br />
*The procedure to [[Firefox#Enable_spell_checking|enable spell checking]] in Firefox may need to be redone, or else the check-as-you-type spelling might not work after renaming the user.<br />
*Certain Thunderbird addons, like [http://enigmail.mozdev.org/home/index.php Enigmail], may need to be reinstalled.<br />
*Anything on your system (desktop shortcuts, shell scripts, etc.) that uses an absolute path to your home dir (i.e. {{ic|/home/oldname}}) will need to be changed to reflect your new name. To avoid these problems in shell scripts, simply use the {{Ic|~}} or {{Ic|$HOME}} variables for home directories.<br />
*Also don't forget to edit accordingly the configuration files in {{ic|/etc}} that relies on your absolute path (i.e. Samba, CUPS, so on). A nice way to learn what files you need to update involves using the grep command this way: {{ic|# grep -r {old_user} *}}</div>Chehrihttps://wiki.archlinux.org/index.php?title=Touchscreen&diff=283734Touchscreen2013-11-20T06:05:51Z<p>Chehri: Changed "tab" to "tap"</p>
<hr />
<div>[[zh-CN:Touchscreen]]<br />
[[Category:Input devices]]<br />
{{Merge|Calibrating Touchscreen}}<br />
{{out of date}}<br />
<br />
If you ever tried to set up a touchscreen device in linux, you might have noticed that it's either working out of the box (besides some calibration) or is very tedious, especially when it isn't supported by the kernel.<br />
<br />
== Introduction ==<br />
This article assumes that your touchscreen device is supported by the kernel (e.g. by the usbtouchscreen module).<br />
That means there exists a /dev/input/event* node for your device. Check out<br />
less /proc/bus/input/devices<br />
to see if your device is listed or try<br />
cat /dev/input/event? # replace ? with the event numbers<br />
for every of your event nodes while touching the display.<br />
<br />
If you found the corresponding node, it's likely that you will be able to get the device working.<br />
<br />
== Available X11 drivers ==<br />
There are a lot of touchscreen input drivers for X11 out there. The most common ones are in the ''extra'' repository:<br />
* {{AUR|xf86-input-evtouch}} (in AUR)<br />
* {{Pkg|xf86-input-elographics}}<br />
<br />
Less common drivers, not contained in the repository, are:<br />
* xf86-input-magictouch<br />
* xf86-input-mutouch<br />
* xf86-input-plpevtch<br />
* xf86-input-palmax<br />
* xf86-input-elo2300 (*)<br />
* xf86-input-microtouch (*)<br />
* xf86-input-penmount (*)<br />
(Note: (*) are deprecated and thus were removed from the repos [https://www.archlinux.org/news/333/])<br />
<br />
Proprietary drivers exist for some devices (e.g.: {{AUR|xf86-input-egalax}}), but it's recommended to try the open source drivers first.<br />
<br />
Depending on your touchscreen device choose an appropriate driver.<br />
<br />
The evtouch input drivers support a wide variety of touchscreens from different vendors like Fujitsu, eGalax, IDEACO, ITM, and Touchkit.<br />
{{Box YELLOW||Since I've only got one touchscreen device (USB 0eef:0001 D-WAV Scientific Co., Ltd eGalax TouchScreen) which works with the evtouch driver I confine myself to this driver. Perhaps someone can add details about how to set up other drivers.}}<br />
<br />
== evtouch drivers ==<br />
<br />
First, install [https://aur.archlinux.org/packages.php?ID=22758 xf86-input-evtouch] from the [[AUR]].<br />
<br />
This package already includes a set of udev rules to create a permanent node for your input device in {{ic|/etc/udev/rules.d/69-touchscreen.rules}}.<br />
<br />
If everything worked fine so far, you should have a symlink {{ic|/dev/input/evtouch_event}} to your input device. If not, your touch device might not work with evtouch, but you can add a custom udev rule for your device and try it anyway.<br />
<br />
In case you configured X server to use HAL hot-plugging, the touchscreen should work now after restarting the X server.<br />
Else you have to add the corresponding "InputDevice" section to xorg.conf as described on [http://www.conan.de/touchscreen/evtouch.html evtouch's webside].<br />
<br />
=== Calibration ===<br />
It's assumed that you have the touchscreen working now in X11 and that you're using hot-plugging for configuration. If you manually set up your input devices and thus switched off hot-plugging, you have to add the X11 options of this section to the xorg.conf file instead (see [http://www.conan.de/touchscreen/evtouch.html evtouch's webside] for details again).<br />
<br />
==== Rough calibration ====<br />
For touchscreen calibration the {{AUR|xf86-input-evtouch}} package includes a calibration program.<br />
sudo /usr/lib/xf86-input-evtouch/calibrate.sh<br />
No matter whether you started it from TTY or X11, this will start a new X server and bring up a white screen. Move the pen around the display border, along all edges a view times to get the minimum and maximum coordinates. Press {{ic|Return}}. Then tap exactly on the red cross. The next cross will turn red, touch it again and repeat this procedure for all crosses.<br />
When your done you should return to command line. The calibration data was written to {{ic|/etc/evtouch/config}}.<br />
<br />
To restore the calibration data after booting add evtouch_config to the DAEMONS variable in {{ic|/etc/rc.conf}}<br />
DAEMONS=( ... evtouch_config ... )<br />
This will read the calibration data from {{ic|/etc/evtouch/config}} and set the corresponding X options using HAL.<br />
<br />
You can now (re)start your X server and enjoy your calibrated touchscreen.<br />
<br />
==== Fine calibration (optional) ====<br />
If your not satisfied with the calibration you can do further tweaking by changing the values in {{ic|/etc/evtouch/config}} manually.<br />
MINX, MINY, MAXX, MAXY are the minimal and maximal coordinates and the nine X?,Y? pairs are the coordinates of the calibration points in the order you touched them.<br />
<br />
==== Correct orientation of the coordinate system ====<br />
The 9 point calibration assures that the coordinate axis are orientated in a way that your cursor moves to the right when your pen does (due to the signs of the X,Y pairs). In case you nevertheless notice your cursor is moving in the wrong direction you can add<br />
hal_set swapx 1<br />
hal_set swapy 1<br />
to /etc/rc.d/evtouch_config (of course this will get overwritten when you upgrade the package)<br />
<br />
When X and Y axis are swaped and your touchscreen uses the usbtouchscreen kernel module you can add the following line to {{ic|/etc/modprobe.d/modprobe.conf}}<br />
options usbtouchscreen swap_xy=1<br />
<br />
Correct orientation can also be done using scripts which utilize xrandr and xinput.<br />
''This was used and tested on a thinkpad x220t.''<br />
A shell script to make the rotation (portrait view) and fix the coordinate system for the touch screen would be<br />
#!/bin/bash<br />
xrandr --screen 0 -o right<br />
xinput set-prop "Wacom ISDv4 E6 Pen" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1<br />
''exchanging "Wacom ISDv4 E6 Pen" with your input device from''<br />
xinput list<br />
The shell script should be made executable by<br />
chmod +x nameofscript.sh<br />
A script to change orientation back would be <br />
#!/bin/bash<br />
xrandr --screen 0 -o normal <br />
xinput set-prop "Wacom ISDv4 E6 Pen" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1<br />
<br />
==== Make the calibration persistent to unplugging or suspending ====<br />
You may notice that after unplugging the touch device and replugging it while the X server is running, your calibration is messed up. The same happens when you resume from hibernation or suspend.<br />
<br />
The reason is, that your calibration setting get set only once, at boot time by evtouch_config. When you unplug it the settings are removed when evtouch is unloaded.<br />
On plugging it in HAL sets the default settings as specified in {{ic|/usr/share/hal/fdi/policy/20thirdparty/50-....fdi}} and loads the evtouch driver, which reads the calibration settings into its memory. Therefore it doesn't work to simply call evtouch_config while the X window system is running.<br />
<br />
The only way I found to make the calibration settings survive a replug-in or a hibernation is to set them directly in the HAL policy file.<br />
The following command converts the calibration settings to HAL policy format and prints the result on stdout.<br />
awk -F= '{print " <merge key=\"input.x11_options."tolower($1)"\" type=\"string\">"$2"</merge>"}' /etc/evtouch/config<br />
Replace the corresponding merge commands in the policy file ({{ic|/usr/share/hal/fdi/policy/20thirdparty/50-....fdi}}) corresponding to your device.<br />
<br />
Of course you do not need the evtouch_config daemon any more when you use this method, so you can remove it from {{ic|/etc/rc.conf}}.<br />
<br />
'''Note:''' when you have problems with right clicking or drag and drop you can try tweaking the settings ([http://www.conan.de/touchscreen/evtouch.html] [http://www.conan.de/touchscreen/libtouch.html]) in the fdi file. You can also set the swapx, swapy options here in case you need them.<br />
<br />
'''WARNING:''' The fdi files will be overwritten when you upgrade {{AUR|xf86-input-evtouch}}, so '''all your changes will be lost'''.<br />
<br />
== Using a touchscreen in a multi-head setup ==<br />
To use multiple displays (some of which are touchscreens), you need to tell Xorg the mapping between the touch surface and the screen. <br />
<br />
This can be done very easily with xinput:<br />
<br />
Take for example the setup of having a wacom tablet and an external monitor. When we type xrandr we get a list of our two displays:<br />
{{bc|<br />
$ xrandr<br />
Screen 0: minimum 320 x 200, current 2944 x 1080, maximum 8192 x 8192<br />
LVDS1 connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm<br />
1024x768 60.0*+<br />
800x600 60.3 56.2 <br />
640x480 59.9 <br />
VGA1 connected 1920x1080+1024+0 (normal left inverted right x axis y axis) 477mm x 268mm<br />
1920x1080 60.0*+<br />
1600x1200 60.0 <br />
1680x1050 60.0 <br />
1680x945 60.0 <br />
}}<br />
<br />
You see we have two displays here. LVDS1 and VGA1. LVDS1 is the display internal to the tablet, and VGA1 is the external monitor. We wish to map our stylus input to LVDS1. So we have to find the ID of the stylus input:<br />
{{bc|<br />
$ xinput --list<br />
⎡ Virtual core pointer id&#61;2 [master pointer (3)]<br />
⎜ ↳ Virtual core XTEST pointer id&#61;4 [slave pointer (2)]<br />
⎜ ↳ QUANTA OpticalTouchScreen id&#61;9 [slave pointer (2)]<br />
⎜ ↳ TPPS/2 IBM TrackPoint id&#61;11 [slave pointer (2)]<br />
⎜ ↳ Serial Wacom Tablet WACf004 stylus id&#61;13 [slave pointer (2)]<br />
⎜ ↳ Serial Wacom Tablet WACf004 eraser id&#61;14 [slave pointer (2)]<br />
⎣ Virtual core keyboard id&#61;3 [master keyboard (2)]<br />
↳ Virtual core XTEST keyboard id&#61;5 [slave keyboard (3)]<br />
↳ Power Button id&#61;6 [slave keyboard (3)]<br />
↳ Video Bus id&#61;7 [slave keyboard (3)]<br />
↳ Sleep Button id&#61;8 [slave keyboard (3)]<br />
↳ AT Translated Set 2 keyboard id&#61;10 [slave keyboard (3)]<br />
↳ ThinkPad Extra Buttons id&#61;12 [slave keyboard (3)]<br />
}}<br />
<br />
We see that we have two stylus inputs who's ID's are 13 and 14. We now need to simply map our inputs to our output like so:<br />
<br />
{{bc|<br />
<br />
xinput --map-to-output 13 LVDS1<br />
xinput --map-to-output 14 LVDS1<br />
}}<br />
<br />
More info can be found at [[Calibrating_Touchscreen]]</div>Chehrihttps://wiki.archlinux.org/index.php?title=GnuPG&diff=282692GnuPG2013-11-13T19:51:47Z<p>Chehri: </p>
<hr />
<div>[[Category:Security]]<br />
GnuPG can be used to sign and encrypt files or mails.<br />
<br />
== Installation ==<br />
<br />
[[pacman|Install]] {{Pkg|gnupg}}, available in the [[official repositories]].<br />
<br />
==Environment Variables==<br />
{{ic|GnuPGP}} uses the directory pointed to by {{ic|$GNUPGHOME}} to store all of its configuration files. By default {{ic|$GNUPGHOME}} isn't set and your {{ic|$HOME}} is used instead, thus you will find a {{ic|~/.gnupg}} directory right after the install. You may change this default setting by putting this line in one of your regular [[Startup_files|startup files]]<br />
export GNUPGHOME&#61;"/path/to/gnupg/directory"<br />
{{Note| by default, the gnupg directory has a particular [[Permissions]] set to ''600''. Only the owner of the directory has permission to read and write (''r'',''w''). This is for security purposes and should not be changed. In case this directory or any file inside it does not follow this security measure, you will get warnings about unsafe file and home directory permissions.}}<br />
<br />
== Basic keys management ==<br />
<br />
=== Create key ===<br />
<br />
* Set stronger algorithms to be used first:<br />
# printf "\npersonal-digest-preferences SHA512\ncert-digest-algo SHA512\ndefault-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed" >> ~/.gnupg/gpg.conf<br />
<br />
* Generate a private key by typing in a terminal: <br />
# gpg --gen-key<br />
<br />
You will be asked several questions. In general, most users will want both a RSA (sign only) and a RSA (encrypt only) key. It is advised t use a keysize of 4096 bits (default is 2048).<br />
<br />
While having an expiration date for subkeys isn't technically necessary, it is considered good practice. A period of a year is generally good enough for the average user. This way even if you lose access to your keyring, it will allow others to know that it is no longer valid.<br />
<br />
* Set expiration date (repeat for both/all subkeys)<br />
# gpg --edit-key 'Your Name'<br />
# key [number]<br />
# expire<br />
# save<br />
<br />
* Generate an ASCII version of your public key (e.g. to distribute it by e-mail):<br />
# gpg --armor --output public.key --export 'Your Name'<br />
<br />
* Register your key with a public PGP key server, so that others can retrieve your key without having to contact you directly:<br />
# gpg --keyserver pgp.mit.edu --send-keys ''Key Id''<br />
<br />
=== Rotating subkeys ===<br />
<br />
{{Warning|'''Never''' delete your expired or revoked subkeys unless you have a good reason. Doing so will cause you to lose the ability to decrypt files encrypted with the old subkey. Please '''only''' delete expired or revoked keys from other users to clean your keyring.}}<br />
<br />
If you have set your subkeys to expire after a set time, you will have to create new ones. Do this a few weeks in advanced to allow others to update their keyring.<br />
<br />
* Create new subkey (repeat for both signing and encrypting key)<br />
# gpg --edit-key 'Your Name'<br />
# addkey<br />
<br />
And answer the following questions it asks (see previous section for suggested settings).<br />
<br />
* Save changes<br />
# save<br />
<br />
* Update it to a keyserver.<br />
# gpg --keyserver pgp.mit.edu --send-keys ''Key Id''<br />
<br />
{{Note|Revoking expired subkeys is unnecessary and arguably bad form. If you are constantly revoking keys, it may cause others to lack confidence in you.}}<br />
<br />
=== Import key ===<br />
<br />
* Import a public key to your public key ring:<br />
# gpg --import public.key<br />
<br />
* Import a private key to your secret key ring:<br />
# gpg --import private.key<br />
<br />
=== List keys ===<br />
<br />
* Keys in your public key ring:<br />
# gpg --list-keys<br />
<br />
* Keys in your secret key ring:<br />
# gpg --list-secret-keys<br />
<br />
== Basic usage ==<br />
<br />
You can use gnupg to encrypt your sensitive documents, but only individual files at a time.<br />
<br />
For example, to decrypt a file, use:<br />
# gpg -d secret.tar.gpg<br />
<br />
You'll be prompted to enter your passphrase.<br />
<br />
If you want to encrypt directories or a whole file-system you should consider using [[TrueCrypt]], though you can always tarball various files and then encrypt them.<br />
<br />
=== Symmetric Encryption ===<br />
<br />
== gpg-agent ==<br />
<br />
{{Ic|Gpg-agent}} is mostly used as daemon to request and cache the password for the keychain. This is useful if GnuPG is used from an external program like a mail client. It can be activated by adding following line in {{ic|~/.gnupg/gpg.conf}}:<br />
use-agent<br />
<br />
This tells GnuPG to use the agent whenever it needs the password. However, the agent needs to run already. To autostart it, create the following file and make it executable, and remember to change the envfile path if you changed your $GNUPGHOME:<br />
{{hc|/etc/profile.d/gpg-agent.sh|2=<nowiki><br />
if [ $EUID -ne 0 ] ; then<br />
envfile="$HOME/.gnupg/gpg-agent.env"<br />
if [[ -e "$envfile" ]] && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then<br />
eval "$(cat "$envfile")"<br />
else<br />
eval "$(gpg-agent --daemon --enable-ssh-support --write-env-file "$envfile")"<br />
fi<br />
export GPG_AGENT_INFO # the env file does not contain the export statement<br />
export SSH_AUTH_SOCK # enable gpg-agent for ssh<br />
fi<br />
</nowiki>}}<br />
<br />
If you don't want gpg-agent to autostart for all users or just want to keep user daemons in the users own configuration files you can add the following entry to your {{Ic|.xinitrc}}:<br />
eval $(gpg-agent --daemon) &<br />
<br />
Log out of your Xsession and log back in. Check if {{Ic|gpg-agent}} is activated<br />
# pgrep agent<br />
<br />
==== Pinentry ====<br />
<br />
Finally, the agent needs to know how to ask the user for the password. This can be set in {{ic|~/.gnupg/gpg-agent.conf}}<br />
<br />
The default uses a gtk dialog. To change it to ncurses or qt, set the following in the above file<br />
<br />
pinentry-program /usr/bin/pinentry-curses<br />
<br />
or<br />
<br />
pinentry-program /usr/bin/pinentry-qt4<br />
<br />
For more options see {{Ic|man gpg-agent}} and {{ic|info pinentry}}.<br />
<br />
== Keysigning Parties ==<br />
To allow users to validate keys on the keyservers and in their keyrings (i.e. make sure they are from whom they claim to be), PGP/GPG uses a so-called "Web of Trust". To build this Web of Trust, many hacker events include keysigning parties.<br />
<br />
The [https://en.wikipedia.org/wiki/Zimmermann%E2%80%93Sassaman_key-signing_protocol Zimmermann-Sassaman] key-signing protocol is a way of making these very effective. [http://www.cryptnet.net/fdp/crypto/keysigning_party/en/keysigning_party.html Here] you'll find a How-To-article.<br />
<br />
=== Caff ===<br />
For an easier process of signing keys and sending signatures to the owners after a keysigning party, you can use the tool 'caff'. It can be installed from the AUR with the package {{AUR|caff-svn}} or bundled together with other useful tools in the package {{AUR|signing-party-svn}}.<br />
Either way, there will be a lot of dependencies installing from the AUR. Alternatively you can install them with<br />
cpanm Any:Moose<br />
cpanm GnuPG::Interface <br />
<br />
To send the signatures to their owners you need a working [https://en.wikipedia.org/wiki/Message_transfer_agent MTA]. If you don't have already one, install [[SSMTP]].<br />
<br />
== Smartcards ==<br />
GnuPG uses scdaemon as an interface to your smartcard reader, please refer to {{Ic|scdaemon}} man page for details.<br />
<br />
=== GnuPG only setups===<br />
If you do not plan to use other cards but those based on GnuPG, you should check the {{Ic|reader-port}} parameter in {{ic|~/.gnupg/scdaemon.conf}}. The value '0' refers to the first available serial port reader and a value of '32768' (default) refers to the first USB reader.<br />
<br />
=== GnuPG together with OpenSC ===<br />
<br />
If you are using any smartcard with an opensc driver (e.g.: ID cards from some countries) you should pay some attention to GnuPG configuration. Out of the box you might receive a message like this when using {{Ic|gpg --card-status}}<br />
<br />
gpg: selecting openpgp failed: ec=6.108<br />
<br />
By default, scdaemon will try to connect directly to the device. This connection will fail if the reader is being used by another process. For example: the pcscd daemon used by OpenSC. To cope with this situation we should use the same underlying driver as opensc so they can work well together.<br />
In order to point scdaemon to use pcscd you should remove {{Ic|reader-port}} from {{ic|~/gnupg/scdaemon.conf}}, specify the location to libpcsclite.so library and disable ccid so we make sure that we use pcscd.<br />
<br />
{{hc|~/scdaemon.conf|<nowiki><br />
pcsc-driver /usr/lib/libpcsclite.so <br />
card-timeout 5<br />
disable-ccid<br />
</nowiki>}}<br />
<br />
Please check {{Ic|man scdaemon}} if you do not use OpenSC.<br />
<br />
== Troubleshooting ==<br />
<br />
=== Su ===<br />
<br />
When using {{Ic|pinentry}}, you must have the proper permisions of the terminal device (e.g. {{Ic|/dev/tty1}}) in use. However, with {{Ic|su}} (or {{Ic|sudo}}), the ownership stays with the original user, not the new one. This means that pinentry will fail, even as root. The fix is to change the permissions of the device at some point before the use of pinentry (i.e. using gpg with an agent). If doing gpg as root, simply change the ownership to root right before using gpg<br />
chown root /dev/ttyN # where N is the current tty<br />
and then change it back after using gpg the first time. The equivalent is likely to be true with {{Ic|/dev/pts/}}. <br />
<br />
{{Note|being part of the group {{Ic|tty}} '''does not''' seem to alleviate the issue, at least as root. (Please confirm with non-superusers)}}<br />
<br />
=== Agent complains end of file ===<br />
<br />
The default pinentry program is pinentry-gtk-2, which needs a DBus session bus to run properly. See [[General Troubleshooting#Session permissions]] for details.<br />
<br />
Alternatively you can use the qt pinentry.<br />
<br />
# ln -sf /usr/bin/pinentry-qt4 /usr/bin/pinentry<br />
<br />
== See also ==<br />
<br />
* [http://blog.sanctum.geek.nz/series/linux-crypto/ A more comprehensive gpg Tutorial]</div>Chehrihttps://wiki.archlinux.org/index.php?title=GnuPG&diff=282690GnuPG2013-11-13T19:41:56Z<p>Chehri: MIT's server seems to be much faster and reliable. Switching unless there's any objections.</p>
<hr />
<div>[[Category:Security]]<br />
GnuPG can be used to sign and encrypt files or mails.<br />
<br />
== Installation ==<br />
<br />
[[pacman|Install]] {{Pkg|gnupg}}, available in the [[official repositories]].<br />
<br />
==Environment Variables==<br />
{{ic|GnuPGP}} uses the directory pointed to by {{ic|$GNUPGHOME}} to store all of its configuration files. By default {{ic|$GNUPGHOME}} isn't set and your {{ic|$HOME}} is used instead, thus you will find a {{ic|~/.gnupg}} directory right after the install. You may change this default setting by putting this line in one of your regular [[Startup_files|startup files]]<br />
export GNUPGHOME&#61;"/path/to/gnupg/directory"<br />
{{Note| by default, the gnupg directory has a particular [[Permissions]] set to ''600''. Only the owner of the directory has permission to read and write (''r'',''w''). This is for security purposes and should not be changed. In case this directory or any file inside it does not follow this security measure, you will get warnings about unsafe file and home directory permissions.}}<br />
<br />
== Basic keys management ==<br />
<br />
=== Create key ===<br />
<br />
* Generate a private key by typing in a terminal: <br />
# gpg --gen-key<br />
<br />
You’ll have to answer a bunch of questions but generally, you can accept the defaults.<br />
<br />
While having an expiration date for subkeys isn't technically necessary, it is considered good practice. A period of a year is generally good enough for the average user. This way even if you lose access to your keyring, it will allow others to know that it is no longer valid.<br />
<br />
* Set expiration date (repeat for both/all subkeys)<br />
# gpg --edit-key 'Your Name'<br />
# key [number]<br />
# expire<br />
# save<br />
<br />
* Generate an ASCII version of your public key (e.g. to distribute it by e-mail):<br />
# gpg --armor --output public.key --export 'Your Name'<br />
<br />
* Register your key with a public PGP key server, so that others can retrieve your key without having to contact you directly:<br />
# gpg --keyserver hkp://subkeys.pgp.net --send-keys ''Key Id''<br />
<br />
=== Rotating subkeys ===<br />
<br />
{{Warning|'''Never''' delete your expired or revoked subkeys unless you have a good reason. Doing so will cause you to lose the ability to decrypt files encrypted with the old subkey. Please '''only''' delete expired or revoked keys from other users to clean your keyring.}}<br />
<br />
If you have set your subkeys to expire after a set time, you will have to create new ones. Do this a few weeks in advanced to allow others to update their keyring.<br />
<br />
* Create new subkey (repeat for both signing and encrypting key)<br />
# gpg --edit-key 'Your Name'<br />
# addkey<br />
<br />
And answer the following questions it asks (validity from 6 months to 2 years is recommended).<br />
<br />
* Save changes<br />
# save<br />
<br />
* Update it to a keyserver.<br />
# gpg --keyserver pgp.mit.edu --send-keys ''Key Id''<br />
<br />
{{Note|Revoking expired subkeys is unnecessary and arguably bad form. If you are constantly revoking keys, it may cause others to lack confidence in you.}}<br />
<br />
=== Import key ===<br />
<br />
* Import a public key to your public key ring:<br />
# gpg --import public.key<br />
<br />
* Import a private key to your secret key ring:<br />
# gpg --import private.key<br />
<br />
=== List keys ===<br />
<br />
* Keys in your public key ring:<br />
# gpg --list-keys<br />
<br />
* Keys in your secret key ring:<br />
# gpg --list-secret-keys<br />
<br />
== Basic usage ==<br />
<br />
You can use gnupg to encrypt your sensitive documents, but only individual files at a time.<br />
<br />
For example, to decrypt a file, use:<br />
# gpg -d secret.tar.gpg<br />
<br />
You'll be prompted to enter your passphrase.<br />
<br />
If you want to encrypt directories or a whole file-system you should consider using [[TrueCrypt]], though you can always tarball various files and then encrypt them.<br />
<br />
=== Symmetric Encryption ===<br />
<br />
== gpg-agent ==<br />
<br />
{{Ic|Gpg-agent}} is mostly used as daemon to request and cache the password for the keychain. This is useful if GnuPG is used from an external program like a mail client. It can be activated by adding following line in {{ic|~/.gnupg/gpg.conf}}:<br />
use-agent<br />
<br />
This tells GnuPG to use the agent whenever it needs the password. However, the agent needs to run already. To autostart it, create the following file and make it executable, and remember to change the envfile path if you changed your $GNUPGHOME:<br />
{{hc|/etc/profile.d/gpg-agent.sh|2=<nowiki><br />
if [ $EUID -ne 0 ] ; then<br />
envfile="$HOME/.gnupg/gpg-agent.env"<br />
if [[ -e "$envfile" ]] && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then<br />
eval "$(cat "$envfile")"<br />
else<br />
eval "$(gpg-agent --daemon --enable-ssh-support --write-env-file "$envfile")"<br />
fi<br />
export GPG_AGENT_INFO # the env file does not contain the export statement<br />
export SSH_AUTH_SOCK # enable gpg-agent for ssh<br />
fi<br />
</nowiki>}}<br />
<br />
If you don't want gpg-agent to autostart for all users or just want to keep user daemons in the users own configuration files you can add the following entry to your {{Ic|.xinitrc}}:<br />
eval $(gpg-agent --daemon) &<br />
<br />
Log out of your Xsession and log back in. Check if {{Ic|gpg-agent}} is activated<br />
# pgrep agent<br />
<br />
==== Pinentry ====<br />
<br />
Finally, the agent needs to know how to ask the user for the password. This can be set in {{ic|~/.gnupg/gpg-agent.conf}}<br />
<br />
The default uses a gtk dialog. To change it to ncurses or qt, set the following in the above file<br />
<br />
pinentry-program /usr/bin/pinentry-curses<br />
<br />
or<br />
<br />
pinentry-program /usr/bin/pinentry-qt4<br />
<br />
For more options see {{Ic|man gpg-agent}} and {{ic|info pinentry}}.<br />
<br />
== Keysigning Parties ==<br />
To allow users to validate keys on the keyservers and in their keyrings (i.e. make sure they are from whom they claim to be), PGP/GPG uses a so-called "Web of Trust". To build this Web of Trust, many hacker events include keysigning parties.<br />
<br />
The [https://en.wikipedia.org/wiki/Zimmermann%E2%80%93Sassaman_key-signing_protocol Zimmermann-Sassaman] key-signing protocol is a way of making these very effective. [http://www.cryptnet.net/fdp/crypto/keysigning_party/en/keysigning_party.html Here] you'll find a How-To-article.<br />
<br />
=== Caff ===<br />
For an easier process of signing keys and sending signatures to the owners after a keysigning party, you can use the tool 'caff'. It can be installed from the AUR with the package {{AUR|caff-svn}} or bundled together with other useful tools in the package {{AUR|signing-party-svn}}.<br />
Either way, there will be a lot of dependencies installing from the AUR. Alternatively you can install them with<br />
cpanm Any:Moose<br />
cpanm GnuPG::Interface <br />
<br />
To send the signatures to their owners you need a working [https://en.wikipedia.org/wiki/Message_transfer_agent MTA]. If you don't have already one, install [[SSMTP]].<br />
<br />
== Smartcards ==<br />
GnuPG uses scdaemon as an interface to your smartcard reader, please refer to {{Ic|scdaemon}} man page for details.<br />
<br />
=== GnuPG only setups===<br />
If you do not plan to use other cards but those based on GnuPG, you should check the {{Ic|reader-port}} parameter in {{ic|~/.gnupg/scdaemon.conf}}. The value '0' refers to the first available serial port reader and a value of '32768' (default) refers to the first USB reader.<br />
<br />
=== GnuPG together with OpenSC ===<br />
<br />
If you are using any smartcard with an opensc driver (e.g.: ID cards from some countries) you should pay some attention to GnuPG configuration. Out of the box you might receive a message like this when using {{Ic|gpg --card-status}}<br />
<br />
gpg: selecting openpgp failed: ec=6.108<br />
<br />
By default, scdaemon will try to connect directly to the device. This connection will fail if the reader is being used by another process. For example: the pcscd daemon used by OpenSC. To cope with this situation we should use the same underlying driver as opensc so they can work well together.<br />
In order to point scdaemon to use pcscd you should remove {{Ic|reader-port}} from {{ic|~/gnupg/scdaemon.conf}}, specify the location to libpcsclite.so library and disable ccid so we make sure that we use pcscd.<br />
<br />
{{hc|~/scdaemon.conf|<nowiki><br />
pcsc-driver /usr/lib/libpcsclite.so <br />
card-timeout 5<br />
disable-ccid<br />
</nowiki>}}<br />
<br />
Please check {{Ic|man scdaemon}} if you do not use OpenSC.<br />
<br />
== Troubleshooting ==<br />
<br />
=== Su ===<br />
<br />
When using {{Ic|pinentry}}, you must have the proper permisions of the terminal device (e.g. {{Ic|/dev/tty1}}) in use. However, with {{Ic|su}} (or {{Ic|sudo}}), the ownership stays with the original user, not the new one. This means that pinentry will fail, even as root. The fix is to change the permissions of the device at some point before the use of pinentry (i.e. using gpg with an agent). If doing gpg as root, simply change the ownership to root right before using gpg<br />
chown root /dev/ttyN # where N is the current tty<br />
and then change it back after using gpg the first time. The equivalent is likely to be true with {{Ic|/dev/pts/}}. <br />
<br />
{{Note|being part of the group {{Ic|tty}} '''does not''' seem to alleviate the issue, at least as root. (Please confirm with non-superusers)}}<br />
<br />
=== Agent complains end of file ===<br />
<br />
The default pinentry program is pinentry-gtk-2, which needs a DBus session bus to run properly. See [[General Troubleshooting#Session permissions]] for details.<br />
<br />
Alternatively you can use the qt pinentry.<br />
<br />
# ln -sf /usr/bin/pinentry-qt4 /usr/bin/pinentry<br />
<br />
== See also ==<br />
<br />
* [http://blog.sanctum.geek.nz/series/linux-crypto/ A more comprehensive gpg Tutorial]</div>Chehrihttps://wiki.archlinux.org/index.php?title=GnuPG&diff=262412GnuPG2013-06-11T20:21:30Z<p>Chehri: /* Basic keys management */</p>
<hr />
<div>[[Category:Security]]<br />
GnuPG can be used to sign and encrypt files or mails.<br />
<br />
== Installation ==<br />
<br />
[[pacman|Install]] {{Pkg|gnupg}}, available in the [[official repositories]].<br />
<br />
== Basic keys management ==<br />
<br />
=== Create key ===<br />
<br />
* Generate a private key by typing in a terminal: <br />
# gpg --gen-key<br />
<br />
You’ll have to answer a bunch of questions but generally, you can accept the defaults.<br />
<br />
While having an expiration date for subkeys isn't technically necessary, it is considered good practice. A period of a year is generally good enough for the average user. This way even if you loose access to your keyring, it will allow others to know that it is no longer valid.<br />
<br />
* Set expiration date (repeat for both/all subkeys)<br />
# gpg --edit-key 'Your Name'<br />
# key [number]<br />
# expire<br />
# save<br />
<br />
* Generate an ASCII version of your public key (e.g. to distribute it by e-mail):<br />
# gpg --armor --output public.key --export 'Your Name'<br />
<br />
* Register your key with a public PGP key server, so that others can retrieve your key without having to contact you directly.:<br />
# gpg --keyserver hkp://subkeys.pgp.net --send-keys ''Key Id''<br />
<br />
=== Rotating subkeys ===<br />
<br />
{{Warning|'''Never''' delete your expired or revoked subkeys unless you have a good reason. Doing so will cause you to lose the ability to decrypt files encrypted with the old subkey. Please '''only''' delete expired or revoked keys from other users to clean your keyring.}}<br />
<br />
If you have set your subkeys to expire after a set time, you will have to create new ones. Do this a few weeks in advanced to allow others to update their keyring.<br />
<br />
* Create new subkey (repeat for both signing and encrypting key)<br />
# gpg --edit-key 'Your Name'<br />
# addkey<br />
<br />
And answer the following questions it asks.<br />
<br />
* Save changes<br />
# save<br />
<br />
* Update it to a keyserver.<br />
# gpg --keyserver hkp://subkeys.pgp.net --send-keys ''Key Id''<br />
<br />
{{Note|Revoking expired subkeys is unnecessary and arguably bad form. If you are constantly revoking keys, it may cause others to lack confidence in you.}}<br />
<br />
=== Import key ===<br />
<br />
* Import a public key to your public key ring:<br />
# gpg --import public.key<br />
<br />
* Import a private key to your secret key ring:<br />
# gpg --import private.key<br />
<br />
=== List keys ===<br />
<br />
* Keys in your public key ring:<br />
# gpg --list-keys<br />
<br />
* Keys in your secret key ring:<br />
# gpg --list-secret-keys<br />
<br />
== Basic usage ==<br />
<br />
You can use gnupg to encrypt your sensitive documents, but only individual files at a time.<br />
<br />
For example, to decrypt a file data, use:<br />
# gpg -d secret.tar.gpg<br />
<br />
You'll be prompted to enter your passphrase.<br />
<br />
If you want to encrypt directories or a whole file-system you should consider use [[truecrypt|Truecrypt]], though you can always tarball various files and then encrypt them.<br />
<br />
=== Symmetric Encryption ===<br />
<br />
== gpg-agent ==<br />
<br />
{{Ic|gpg-agent}} is mostly used as daemon to request and cache the password for the keychain. This is useful if GnuPG is used from an external program like a mail client. It can be activated by adding following line in {{ic|~/.gnupg/gpg.conf}}:<br />
use-agent<br />
<br />
This tells GnuPG to use the agent whenever it needs the password. However, the agent needs to run already. To autostart it, create the following file and make it executable:<br />
{{hc|/etc/profile.d/gpg-agent.sh|2=<nowiki><br />
#!/bin/sh<br />
<br />
envfile="${HOME}/.gnupg/gpg-agent.env"<br />
if test -f "$envfile" && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then<br />
eval "$(cat "$envfile")"<br />
else<br />
eval "$(gpg-agent --daemon --write-env-file "$envfile")"<br />
fi<br />
export GPG_AGENT_INFO # the env file does not contain the export statement<br />
</nowiki>}}<br />
<br />
Add an entry in your {{Ic|.xinitrc}}<br />
eval $(gpg-agent --daemon) &<br />
<br />
Log out your Xsession and login. Check {{Ic|gpg-agent}} is actived<br />
#ps aux | grep agent<br />
<br />
<br />
If you would like to use {{Ic|gpg-agent}} to manage your SSH keys see [[SSH Keys#GnuPG Agent]].<br />
<br />
==== Pinentry ====<br />
<br />
Finally, the agent needs to know how to ask the user for the password. This can be set in {{ic|~/.gnupg/gpg-agent.conf}}<br />
<br />
The default uses a gtk dialog. To change it to ncurses or qt, set the following in the above file<br />
<br />
pinentry-program /usr/bin/pinentry-curses<br />
<br />
or<br />
<br />
pinentry-program /usr/bin/pinentry-qt4<br />
<br />
For more options see {{Ic|man gpg-agent}} and {{ic|info pinentry}}.<br />
<br />
== Smartcards ==<br />
GnuPG uses scdaemon as an interface to your smartcard reader, please refer to {{Ic|scdaemon}} man page for details.<br />
<br />
=== GnuPG only setups===<br />
If you do not plan to use other cards but those based on GnuPG, you should check the {{Ic|reader-port}} parameter in {{ic|~/.gnupg/scdaemon.conf}}. The value '0' refers to the first available serial port reader and a value of '32768' (default) refers to the first USB reader.<br />
<br />
=== GnuPG together with OpenSC ===<br />
<br />
If you are using any smartcard with an opensc driver (e.g.: ID cards from some countries) you should pay some attention to GnuPG configuration. Out of the box you might receive a message like this when using {{Ic|gpg --card-status}}<br />
<br />
gpg: selecting openpgp failed: ec=6.108<br />
<br />
By default, scdaemon will try to connect directly to the device. This connection will fail if the reader is being used by another process. For example: the pcscd daemon used by OpenSC. To cope with this situation we should use the same underlying driver as opensc so they can work well together.<br />
In order to point scdaemon to use pcscd you should remove {{Ic|reader-port}} from {{ic|~/gnupg/scdaemon.conf}}, specify the location to libpcsclite.so library and disable ccid so we make sure that we use pcscd.<br />
<br />
{{hc|~/scdaemon.conf|<nowiki><br />
pcsc-driver /usr/lib/libpcsclite.so <br />
card-timeout 5<br />
disable-ccid<br />
</nowiki>}}<br />
<br />
Please check {{Ic|man scdaemon}} if you do not use OpenSC.<br />
<br />
== Troubleshooting ==<br />
<br />
=== Su ===<br />
<br />
When using {{Ic|pinentry}}, you must have the proper permisions of the terminal device (e.g. {{Ic|/dev/tty1}}) in use. However, with {{Ic|su}} (or {{Ic|sudo}}), the ownership stays with the original user, not the new one. This means that pinentry will fail, even as root. The fix is to change the permissions of the device at some point before the use of pinentry (i.e. using gpg with an agent). If doing gpg as root, simply change the ownership to root right before using gpg<br />
chown root /dev/ttyN # where N is the current tty<br />
and then change it back after using gpg the first time. The equivalent is likely to be true with {{Ic|/dev/pts/}}. <br />
<br />
{{Note|being part of the group {{Ic|tty}} '''does not''' seem to alleviate the issue, at least as root. (Please confirm with non-superusers)}}<br />
<br />
=== Agent complains end of file ===<br />
<br />
The default pinetry program is pinetry-gtk-2, which needs a DBus session bus to run properly. Check $DBUS_SESSION_BUS_ADDRESS, if that's missing you can run<br />
<br />
eval $(dbus-launch --sh-syntax --exit-with-session)<br />
<br />
to provide the bus. dbus-launch as available in {{pkg|dbus}}.<br />
<br />
Alternatively you can use the qt pinetry.<br />
<br />
# ln -sf /usr/bin/pinetry-qt4 /usr/bin/pinetry</div>Chehrihttps://wiki.archlinux.org/index.php?title=Dm-crypt&diff=261732Dm-crypt2013-06-08T00:49:54Z<p>Chehri: /* Creating Disk Partitions */</p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:Security]]<br />
[[Category:File systems]]<br />
[[de:ArchLinux mit verschlüsseltem LVM und Systemd]]<br />
[[fr:LUKS]]<br />
[[ru:System Encryption with LUKS]]<br />
[[zh-CN:System Encryption with LUKS]]<br />
{{Article summary start}}<br />
{{Article summary text|This tutorial will show you how to set up system encryption with LUKS for dm-crypt.}}<br />
{{Article summary heading|Related}}<br />
{{Article summary wiki|Disk Encryption}}<br />
{{Article summary wiki|Removing System Encryption}}<br />
{{Article summary end}}<br />
<br />
This article focuses on how to set up full system encryption on Arch Linux, using dm-crypt with LUKS.<br />
<br />
'''dm-crypt''' is the standard device-mapper encryption functionality provided by the Linux kernel. It can be used directly by those who like to have full control over all aspects of partition and key management.<br />
<br />
'''LUKS''' is an additional convenience layer which stores all of the needed setup information for dm-crypt on the disk itself and abstracts partition and key management in an attempt to improve ease of use.<br />
<br />
For more details on how dm-crypt+LUKS compares to other disk encryption solution, see [[Disk Encryption#Comparison table]].<br />
<br />
== Caveats ==<br />
{{Out of date|As of the [https://www.archlinux.org/news/install-media-20120715-released/ 2012.07.15 installation media release], AIF (the Arch Installation Framework) is no longer included but instead [https://github.com/falconindy/arch-install-scripts Arch Install Scripts] are provided to aid in the installation process. Some of the content still has to get updated on this page. Currently (May 2013) this is Section 8 (Encrypted LVM) in particular and 4.5 (AIF legacy instructions). <br />
Keep in mind while reading that out-of-date content is marked per section (or even per paragraph in some few cases). Hence, it does not imply the next section (or paragraph) is out-of-date either!}}<br />
<br />
== Initial Setup ==<br />
=== Overview and Preparation ===<br />
The installation of a LUKS-encrypted system is largely the same as installing an unencrypted system. Routine creation of an encrypted system follows these general steps:<br />
<br />
::* Secure erasure of the hard disk drive(s)<br />
::* Partitioning and setup of encryption ([[LVM]] optional)<br />
::* Routine package selection and installation<br />
::* System Configuration<br />
<br />
This page covers the first two points in a general way for different configuration options available with LUKS. <br />
<br />
The third and fourth point are covered in the later sections. Since the Arch installation media comes with all the tools required for system encryption, you can follow the [[Installation Guide]] or the [[Beginners' Guide]] after the encrypted partitions are set up. You will have to adjust the system configuration to be able to boot from your LUKS-volumes though. <br />
<br />
{{Warning | Encrypting a partition will erase everything currently on that partition. Please make appropriate data backups prior to starting.}}<br />
<br />
=== Secure erasure of the hard disk drive ===<br />
{{Note|The following methods are specifically to dm-crypt/LUKS. For detailed instructions on how to erase and prepare a drive consult: [[Securely wipe disk]]}}<br />
<br />
Before encrypting a drive, you should perform a secure erase of the disk by overwriting the entire drive with random data. To prevent cryptographic attacks or unwanted [[File Recovery]], this data should be completely indistinguishable from all data later written by dm-crypt.<br />
<br />
In deciding which method to use for secure erasure of a hard disk drive, remember that this will not need to be performed more than once for as long as the drive is used as an encrypted drive.<br />
<br />
==== Use LUKS container as pseudorandom number generator (alternate) ====<br />
<br />
The [http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions#5._Security_Aspects cryptsetup FAQ] mentions a very simple procedure to use an existing dm-crypt-volume to wipe all free space accessible on the underlying block device with random data by acting as a simple pseudorandom number generator. It is also claimed to protect against disclosure of usage patterns.<br />
<br />
{{bc|1=<br />
# dd if=/dev/zero of=/dev/mapper/luks-container}}<br />
<br />
===== Wipe free space with encrypted file after Installation =====<br />
<br />
The same effect can be achieved if a file is created on each encrypted partition that fills the partition completely after the system is installed, booted and filesystems mounted. That is because encrypted data is indistinguishable from random.<br />
<br />
{{bc|1=<br />
# dd if=/dev/zero of=/file/in/luks-container<br />
# rm /file/in/luks-container}}<br />
<br />
Obviously the above process has to be repeated for every container created.<br />
<br />
==== Wipe LUKS keyslots ====<br />
#cryptsetup luksKillSlot <device> <key slot number><br />
<br />
This will only wipe a single keyslot.<br />
<br />
==== Wipe LUKS header ====<br />
The partitions formatted with dm-crypt/LUKS contain a header with the cipher and crypt-options used, which is referred to {{ic|dm-mod}} when opening the blockdevice. After the header the actual random data partition starts. Hence, when de-commissioning a drive (e.g. sale of PC, switch of drives, etc.) it ''may'' be just enough to wipe the header of the partition, rather than overwriting the whole drive - which can be a lengthy process. <br />
<br />
Wiping the LUKS header will delete the PBKDF2-encrypted (AES) master key, salts and so on.<br />
<br />
{{Note|It is crucial to write to the LUKS encrypted partition ({{ic|/dev/sda'''1'''}} in this example) and not directly to the disks device node. If you did set up encryption as a device-mapper layer on top of others, e.g. LVM on LUKS on RAID then write to RAID respectively.}}<br />
<br />
A header with one single default 256 bit size keyslot is 1024KB in size. It is advised to also overwrite the first 4KB written by dm-crypt, so 1028KB have to be wiped. That is {{ic|1052672}} Byte.<br />
<br />
For zero offset use:<br />
#head -c 1052672 /dev/zero > /dev/sda1; sync<br />
<br />
For 512 bit key length (e.g. for aes-xts-plain with 512 bit key) the header is 2MB.<br />
<br />
If in doubt, just be generous and overwrite the first 10MB or so.<br />
<br />
#dd if=/dev/zero of=/dev/sda1 bs=512 count=20480<br />
<br />
{{Note|With a backup-copy of the header data can get rescued but the filesystem was likely damaged as the first encrypted sectors were overwritten. See further sections on how to make a backup of the crucial header blocks.}}<br />
<br />
When wiping the header with random data and the header is followed by encrypted data written ontop random data everything left is random data.<br />
<br />
====Discard/TRIM support for solid state disks (SSD)====<br />
Solid state disk users should be aware that by default, Linux's full-disk encryption mechanisms will ''not'' forward TRIM commands from the filesystem to the underlying disk. The device-mapper maintainers have made it clear that TRIM support will never be enabled by default on dm-crypt devices because of the potential security implications.<br />
<br />
Most users will still want to use TRIM on their encrypted SSDs. Minimal data leakage in the form of freed block information, perhaps sufficient to determine the filesystem in use, may occur on devices with TRIM enabled. An illustration and discussion of the issues arising from activating TRIM is available in the [http://asalor.blogspot.de/2011/08/trim-dm-crypt-problems.html blog] of a {{ic|cryptsetup}} developer.<br />
<br />
As a semi-tangential caveat, it is worth noting that because TRIM provides information to the disk firmware about which blocks contain data, encryption schemes that rely on plausible deniability, like TrueCrypt's hidden volumes, should never be used on a device that utilizes TRIM. This is probably also valid for TC containers within a LUKS encrypted device that uses TRIM.<br />
<br />
TrueCrypt's developers also recommend against using any TC volume on a device that performs wear-leveling techniques to extend the life of the disk; most flash devices, including SSDs and USB flash drives, use mandatory wear-leveling at the firmware level. LUKS devices are probably not vulnerable to problems with wear-leveling if the entire device is blanked before the LUKS partition is initialized. See http://www.truecrypt.org/docs/?s=trim-operation and http://www.truecrypt.org/docs/?s=wear-leveling for more information.<br />
<br />
In {{Pkg|linux}} 3.1 and up, support for dm-crypt TRIM pass-through can be toggled upon device creation or mount with dmsetup. Support for this option also exists in {{Pkg|cryptsetup}} version 1.4.0 and up. To add support during boot, you will need to add {{ic|:allow-discards}} to the {{ic|cryptdevice}} option. The TRIM option may look like this:<br />
cryptdevice=/dev/mapper/root:root:allow-discards<br />
<br />
For the main {{ic|cryptdevice}} configuration options before the {{ic|:allow-discards}} please refer to the sections following. Besides the kernel option, it is also required to mount the filesystem (e.g. {{ic|/dev/mapper/root}} in this example) with the {{ic|discard}} option in {{ic|/etc/fstab}}. For details, please refer to the [[SSD#TRIM|SSD]] page.<br />
<br />
===Partitioning===<br />
<br />
After the drive has been securely overwritten, it is time to create partitions and begin setting up an encrypted system.<br />
<br />
There are multiple ways to create disk partitions:<br />
<br />
::*Standard partitions<br />
::*[[#LVM:_Logical_Volume_Manager|LVM]]<br />
::*[[RAID]]<br />
<br />
LUKS is compatible with systems that require LVM and/or RAID as well as with with standard primary, extended, and logical partitions.<br />
<br />
====Standard Partitions====<br />
<br />
These are the partitions that most people are familiar with. They come in three flavors: primary partitions, extended partitions, and logical partitions.<br />
<br />
;Primary Partitions: These are the normal partitions recognized by the system BIOS. There can be up to four of these stored in the MBR.<br />
<br />
;Extended Partitions: These are primary partitions that also define another partition within themselves. Extended partitions were created to work around the original limit of four primary partitions.<br />
<br />
;Logical Partitions: These are the partitions that are defined within extended partitions.<br />
<br />
====LVM: Logical Volume Manager====<br />
<br />
The LVM allows for creation of volume groups for systems that require complex combinations of multiple hard disk drives and partitions that are not possible with standard partitions. LVM is covered in detail in the [[LVM|Article on LVM]] which is recommended reading prior to continuing with the instructions on [[Dm-crypt_with_LUKS#Encrypting_a_LVM_setup|setting up LUKS with LVM]] located below.<br />
<br />
{{Tip|Btrfs has a built-in [[Btrfs#Subvolumes|Subvolume-Feature]] that fully replaces the need for LVM if no other filesystems are required. An encrypted swap is not possible this way and swap files are [https://btrfs.wiki.kernel.org/index.php/FAQ#Does_btrfs_support_swap_files.3F not supported] by btrfs up to now.}}<br />
<br />
{{Poor writing|Due to uncomprehensible disarrangement this small section on stacking of device-mapper layers was overcomplicated to read. Now different setups are seperated by subsection-headings, nevertheless language and content still need improvement and duplicates should get deleted.}}<br />
<br />
=====LVM on LUKS=====<br />
<br />
There is a growing preference towards logical volume management of LUKS encrypted physical media (LVM on LUKS). The deployment of LVM on LUKS is considered much more generalizable. In a LVM on LUKS scenario, the LUKS-partition has to be opened and mapped before LVM can access the underlaying setup volumes.<br />
<br />
One reason for this is that using LUKS as the lowest level of infrastructure most closely approximates the deployment of physical disks with built-in hardware encryption. In that case, logical volume management would be layered on top of the hardware encryption - usage of LUKS would be superfluous.<br />
<br />
=====LUKS on LVM=====<br />
<br />
It is possible there may exist usage scenarios where encrypting logical volumes rather than physical disks is required (LUKS on LVM).<br />
A usage scenario for LUKS on LVM exists where utmost flexibility for assigning available diskspace or a mix of unencrypted and encrypted volumes is desired. Upon boot the LVM is setup and assigned before the LUKS-encrypted volumes are opened. In order to manage changes of volumes in a LUKS on LVM setup, both module layers' setup have to be taken into account, i.e. shrinking or expanding an encrypted volume has to include the resizing of the encrypted LUKS blockdevice to ensure integrity of it and the filesystem. That said, in simpler scenarios the usage of LVM may be superfluous.<br />
<br />
====Creating Disk Partitions====<br />
<br />
Disk partitions are created using:<br />
<br />
# cfdisk<br />
<br />
This will display a graphical interface for creating disk partitions.<br />
<br />
There are two required partitions for any encrypted system:<br />
<br />
; root file system: {{ic|'''/'''}} Will be encrypted and store all system and user files ({{ic|/usr}}, {{ic|/bin}}, {{ic|/var}}, {{ic|/home}}, etc.)<br />
<br />
; initial boot partition: {{ic|'''/boot'''}} Will ''not'' be encrypted; the bootloader needs to access the {{ic|/boot}} directory where it will load the initramfs/encryption modules needed to load the rest of the system which ''is'' encrypted (see [[Mkinitcpio]] for details). For this reason, {{ic|/boot}} needs to reside on its own, unencrypted partition.<br />
{{Out of date|It is now possible to include /boot on a LUKS container thanks to grub 2.00. Zack Buhman (buhman) has proposed a patch which allows this. [https://bugs.archlinux.org/task/31877] This allows kexec to be used to start a new kernel in remote situations. It also removes any possibility of the kernel being tampered with (though grub is still unencrypted; store on a removable drive for added safety).}}<br />
<br />
{{Note| A swap partition is optional; it can be encrypted with dm-crypt/LUKS. See [[#Encrypting_the_Swap_partition|Encrypting the Swap Partition]] for details.}}<br />
<br />
=====Single Disk Systems=====<br />
<br />
Depending on the system demands, there may be additional partitions desired. These partitions can be individually created at this level by defining separate primary or extended/logical partitions. However, if LVM is to be used, the space unoccupied by {{ic|/boot}} and swap should be defined as single large partition which will be divided up later at the LVM level.<br />
<br />
=====Multiple Disk Systems=====<br />
<br />
In systems that will have multiple hard disk drives, the same options exist as a single disk system. After the creation of the {{ic|/boot}} and swap partitions, the remaining free space on physical disks can divided up into their respective partitions at this level, or large partitions can define all free space per physical disk with intent to partition them within the LVM.<br />
<br />
== Configuring LUKS ==<br />
This section covers how to manually utilize LUKS from the command line to encrypt a system. <br />
<br />
=== Mapping Physical Partitions to LUKS ===<br />
After writing the partition table to the MBR (optionally set up LVM thereafter) the next step is to create the LUKS and dm-crypt magic and make device mapper mount it to the filesystem of the installation system.<br />
<br />
When creating LUKS partitions they must be associated with a key. The key is used to unlock the header of the LUKS-encrypted partitions.<br />
<br />
A key is either a: <br />
<br />
*Passphrase<br />
*Keyfile <br />
<br />
It is possible to define up to 8 different keys per LUKS partition. This enables the user to create access keys for save backup storage. Also a different key-slot could be used to grant access to a partition to a user by issuing a second key and later revoking it again without the need to re-encrypt the partition. Having in mind that further passphrases or keyfiles can be added later easily at any time might make the choice for the initial key easier. <br />
<br />
==== Using LUKS to Format Partitions with a Passphrase ====<br />
{{Note|Using a passphrase to decrypt LUKS partitions automatically from {{ic|/etc/crypttab}} is [http://www.mail-archive.com/arch-projects@archlinux.org/msg02115.html deprecated.]}}<br />
<br />
Cryptsetup is used to interface with LUKS for formatting, mounting and unmounting encrypted partitions.<br />
<br />
Usage:<br />
# cryptsetup [OPTION...] <action> <action-specific><br />
<br />
Example:<br />
# cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random --verify-passphrase luksFormat <device> <br />
<br />
Common options used with luksFormat:<br />
<br />
{| class="wikitable" style="margin:0 5em 0.5em 0.5em 0.5em;"<br />
! scope="col" style="text-align:left" | Available&nbsp;options<br />
! scope="col" style="text-align:left" | Cryptsetup (<1.6.0) defaults <br />
! scope="col" style="text-align:left" | Comment<br />
! scope="col" style="text-align:left" | Example<br />
! scope="col" style="text-align:left" | Comment<br />
|-<br />
! scope="row" style="text-align:right" | --cipher, -c<br />
| {{ic|aes-cbc-essiv:sha256}}<br />
| Use the AES-[[Disk_Encryption#Ciphers_and_modes_of_operation|cipher]] with [http://en.wikipedia.org/wiki/Disk_encryption_theory#Cipher-block_chaining_.28CBC.29 CBC/ESSIV].<br />
| {{ic|aes-xts-plain64}}<br />
| [http://en.wikipedia.org/wiki/Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29 XTS]. For volumes >2TiB use {{ic|aes-xts-plain64}} (requires kernel >= 2.6.33).<br />
|-<br />
! scope="row" style="text-align:right" | --key-size, -s<br />
| {{ic|256}}<br />
| The cipher is used with 256 bit key-size.<br />
| {{ic|512}}<br />
| [http://en.wikipedia.org/wiki/XEX-TCB-CTS#Issues_with_XTS XTS splits the supplied key] into fraternal twins. For an effective AES-256 the XTS key-size must be {{ic|512}}.<br />
|-<br />
! scope="row" style="text-align:right" | --hash, -h<br />
| {{ic|sha1}}<br />
| Hash algorithm used for [[Disk_Encryption#Keys.2C_keyfiles_and_passphrases|PBKDF2]].<br />
| {{ic|sha512}}<br />
| <br />
|-<br />
! scope="row" style="text-align:right" | --iter-time, -i<br />
| {{ic|1000}}<br />
| Number of milliseconds to spend with PBKDF2 passphrase processing.<br />
| {{ic|5000}}<br />
| Using a hash stronger than sha1 results in less iterations if iter-time is not increased.<br />
|-<br />
! scope="row" style="text-align:right" | --use-random<br />
| {{ic|--use-'''u'''random}}<br />
| /dev/u[[Random|random]] is used as randomness source for the (long-term) volume master key.<br />
| {{ic|--use-random}}<br />
| Avoid generating an insecure master key if low on entropy. Will block if the entropy pool is used up.<br />
|-<br />
! scope="row" style="text-align:right" | --verify-passphrase, -y<br />
| Yes<br />
| Default only for luksFormat and luksAddKey.<br />
| -<br />
| No need to type for archlinux at the moment.<br />
|}<br />
<br />
Please note that the above compares historic cryptsetup defaults in the left column. With release 1.6.0 the defaults have changed to an AES cipher in XTS mode, but with other options than the right column example (e.g. an effective key-size of 128-bit). The defaults can be checked with the tail output of <br />
# cryptsetup --help<br />
When deciding on the encryption cipher to use during blockdevice creation, it has to be taken into account that a number of the options stated affect system performance just for creating the initial crypt-blockdevice or opening it, but not the crypto and disk-io operations when the system is running. The throughput and security of the crypted data itself depends on the cipher and key-size. The used hash, iteration-time and random source options affect the cryptographic security of the master-key creation and processing time needed to unlock it in the future. <br />
<br />
A full list of options {{ic|cryptsetup}} accepts can be found in the [http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=cryptsetup manpage]. Furthermore, {{ic|cryptsetup}} now has a feature to benchmark the crypto performance of the processor:<br />
# cryptsetup benchmark <br />
can give guidance on deciding for a cipher to use prior to installation. <br />
<br />
In the following examples for creating LUKS partitions, we will use the AES cipher in XTS mode; at present this is not only the default, but also a most generally used preferred cipher.<br />
More information this and other ciphers used with cryptsetup can be found here: [[Wikipedia:Block_cipher]]<br />
<br />
'''Formatting LUKS Partitions'''<br />
<br />
First of all make sure the device mapper kernel module is loaded by executing the following: {{ic|# modprobe dm_mod}}<br />
<br />
In order to format a desired partition as an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup -c <cipher> -y -s <key size> luksFormat /dev/<partition name>|<br />
Enter passphrase: <password><br />
Verify passphrase: <password>}}<br />
<br />
Check results:<br />
# cryptsetup luksDump /dev/<drive><br />
<br />
This should be repeated for all partitions except for {{ic|/boot}} and possibly swap. You will note that the dump not only shows the cipher header information, but also the key-slots in use for the LUKS partition. <br />
<br />
The example below will create an encrypted root partition using the AES cipher in XTS mode (generally referred to as ''XTS-AES'').<br />
{{bc|# cryptsetup -c aes-xts-plain -y -s 512 luksFormat /dev/sda2}}<br />
<br />
{{Note|If hibernation usage is planned, swap must be encrypted in this fashion; otherwise, if hibernation is not a planned feature for the system, encrypting the swap file will be performed in a alternative manner.}}<br />
<br />
{{Warning|Irrespective of the chosen partitioning method, the {{ic|/boot}} partition must remain separate and unencrypted in order to load the kernel and boot the system.}}<br />
<br />
'''Unlocking/Mapping LUKS Partitions with the Device Mapper'''<br />
<br />
Once the LUKS partitions have been created it is time to unlock them.<br />
<br />
The unlocking process will map the partitions to a new device name using the device mapper. This alerts the kernel that {{ic|/dev/<partition name>}} is actually an encrypted device and should be addressed through LUKS using the {{ic|/dev/mapper/<name>}} so as not to overwrite the encrypted data. To guard against accidental overwriting, read about the possibilities to [[LUKS#Backup_the_cryptheader|backup the cryptheader]] after finishing setup.<br />
<br />
In order to open an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup luksOpen /dev/<partition name> <device-mapper name>|<br />
Enter any LUKS passphrase: <password><br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
Usually the device mapped name is descriptive of the function of the partition that is mapped, example:<br />
<br />
; cryptsetup luksOpen /dev/sda2 swap: Once opened, the swap partition device address would be {{ic|/dev/mapper/swap}} instead of {{ic|/dev/sda2}}.<br />
<br />
; cryptsetup luksOpen /dev/sda3 root: Once opened, the root partition device address would be {{ic|/dev/mapper/root}} instead of {{ic|/dev/sda3}}.<br />
<br />
; cryptsetup luksOpen /dev/sda3 lvmpool (alternate): For setting up [[#LVM:_Logical_Volume_Manager|LVM]] ontop the encryption layer the device file for the decrypted volume group would be anything like {{ic|/dev/mapper/lvmpool}} instead of {{ic|/dev/sda3}}. LVM will then give additional names to all logical volumes created, e.g. {{ic|/dev/mapper/lvmpool-root}} and {{ic|/dev/mapper/lvmpool-swap}}.<br />
<br />
In order to write encrypted data into the partition it must be accessed through the device mapped name.<br />
<br />
{{Note|Since {{ic|/boot}} is not encrypted, it does not need a device mapped name and will be addressed as {{ic|/dev/sda1}}.}}<br />
<br />
==== Using LUKS to Format Partitions with a Keyfile ====<br />
{{Note|This section describes using a plaintext keyfile. If you want to encrypt your keyfile giving you two factor authentication see [https://wiki.archlinux.org/index.php/System_Encryption_with_LUKS#Using_GPG_or_OpenSSL_Encrypted_Keyfiles Section 9] for details, but please still read this section.}}<br />
<br />
'''What is a Keyfile?'''<br />
<br />
A keyfile is any file in which the data contained within it is used as the passphrase to unlock an encrypted volume.<br />
Therefore if these files are lost or changed, decrypting the volume will no longer be possible.<br />
<br />
{{Tip|Define a passphrase in addition to the keyfile for backup access to encrypted volumes in the event the defined keyfile is lost or changed.}}<br />
<br />
'''Why use a Keyfile?'''<br />
<br />
There are many kinds of keyfile. Each type of keyfile used has benefits and disadvantages summarized below:<br />
<br />
:'''keyfile.passphrase:'''<br />
::this is my passphrase I would have typed during boot but I have placed it in a file instead<br />
<br />
This is a keyfile containing a simple passphrase. The benefit of this type of keyfile is that if the file is lost the data it contained is known and hopefully easily remembered by the owner of the encrypted volume. However the disadvantage is that this does not add any security over entering a passphrase during the initial system start.<br />
<br />
:'''keyfile.randomtext:'''<br />
::fjqweifj830149-57 819y4my1- 38t1934yt8-91m 34co3;t8y;9p3y-<br />
<br />
This is a keyfile containing a block of random characters. The benefit of this type of keyfile is that it is much more resistant to dictionary attacks than a simple passphrase. An additional strength of keyfiles can be utilized in this situation which is the length of data used. Since this is not a string meant to be memorized by a person for entry, it is trivial to create files containing thousands of random characters as the key. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase.<br />
<br />
:'''keyfile.binary:'''<br />
::where any binary file, images, text, video could be chosen as the keyfile<br />
<br />
This is a binary file that has been defined as a keyfile. When identifying files as candidates for a keyfile, it is recommended to choose files that are relatively static such as photos, music, video clips. The benefit of these files is that they serve a dual function which can make them harder to identify as keyfiles. Instead of having a text file with a large amount of random text, the keyfile would look like a regular image file or music clip to the casual observer. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase. Additionally, there is a theoretical loss of randomness when compared to a randomly generated text file. This is due to the fact that images, videos and music have some intrinsic relationship between neighboring bits of data that does not exist for a text file. However this is controversial and has never been exploited publicly.<br />
<br />
'''Creating a Keyfile with Random Characters'''<br />
<br />
Here {{ic|dd}} is used to generate a keyfile of 2048 random bytes.<br />
<br />
# dd if=/dev/urandom of=mykeyfile bs=512 count=4<br />
<br />
The usage of {{ic|dd}} is similar to initially wiping the volume with random data prior to encryption. <br />
<br />
{{Warning|Do not use [[badblocks]] here. It only generate a random pattern which just repeats its randomness over and over again.}}<br />
<br />
'''Creating a new LUKS encrypted partition with a Keyfile'''<br />
<br />
When creating a new LUKS encrypted partition, a keyfile may be associated with the partition on its creation using:<br />
<br />
# cryptsetup -c <desired cipher> -s <key size> luksFormat /dev/<volume to encrypt> '''/path/to/mykeyfile'''<br />
<br />
This is accomplished by appending the bold area to the standard cryptsetup command which defines where the keyfile is located.<br />
<br />
==== Adding Additional Passphrases or Keyfiles to a LUKS Encrypted Partition ====<br />
<br />
LUKS supports the association of up to 8 keyslots with any single encrypted volume.<br />
Keyslots can be either keyfiles or passphrases.<br />
<br />
Once an encrypted partition has been created, the initial keyslot 0 is created. Additional keyslots are numbered from 1 to 7.<br />
<br />
Adding new keyslots is accomplished using cryptsetup with the {{ic|luksAddKey}} action.<br />
<br />
Don't forget wiping unused keyslots with {{ic|luksKillSlot}} as described in [[#Wipe LUKS keyslots]].)<br />
<br />
{{hc|# cryptsetup luksAddKey /dev/<volume> (/path/to/<additionalkeyfile>)|<br />
Enter any passphrase:<br />
Enter new passphrase for key slot:<br />
Verify passphrase:}}<br />
<br />
Where <device> is the volume containing the LUKS header to wich the new keyslot is added. This works on header backup files as well.<br />
<br />
If {{ic|/path/to/<additionalkeyfile>}} is given, cryptsetup will add a new keyslot for <additionalkeyfile>. Otherwise a new passphrase will be prompted for twice.<br />
<br />
For adding keyslots cryptsetup has to decrypt the master key from an existing keyslot so it first asks for "any passphrase" (of an existing keyslot).<br />
<br />
For getting the master key from an existing keyfile keyslot the {{ic|--key-file}} or {{ic|-d}} option followed by the "old" <keyfile> will try to unlock all available keyfile keyslots.<br />
<br />
# cryptsetup luksAddKey /dev/mapper/<device> (/path/to/<additionalkeyfile>) -d /path/to/<keyfile><br />
<br />
=== Storing the Key File ===<br />
<br />
==== External Storage on a USB Drive ====<br />
<br />
=====Preparation for Persistent block device naming=====<br />
<br />
For reading the file from an external storage device it is very convenient to access it through udev's [[Persistent block device naming]] features and not by ordinary device nodes like {{ic|/dev/sdb1}} whose naming depends on the order in which devices are plugged in. So in order to assure that the {{ic|encrypt}} HOOK in the initcpio finds your keyfile, you must use a permanent device name. <br />
<br />
=====Persistent symlinks=====<br />
<br />
{{Merge|Persistent block device naming|Anything not specific to storing LUKS keyfiles should get merged there.}}<br />
<br />
A quick method (as opposed to setting up a [[udev]] rule) for doing so involves referencing the right partition by its UUID, id (based on hardware info and serial number) or filesystem label.<br />
<br />
Plug the device in and print every file name under /dev/disk:<br />
<br />
{{hc|#ls -lR /dev/disk/|<br />
/dev/disk/:<br />
total 0<br />
drwxr-xr-x 2 root root 180 Feb 12 10:11 by-id<br />
drwxr-xr-x 2 root root 60 Feb 12 10:11 by-label<br />
drwxr-xr-x 2 root root 100 Feb 12 10:11 by-path<br />
drwxr-xr-x 2 root root 180 Feb 12 10:11 by-uuid<br />
<br />
/dev/disk/by-id:<br />
total 0<br />
lrwxrwxrwx 1 root root 9 Feb 12 10:11 usb-Generic_STORAGE_DEVICE_000000014583-0:0 -> ../../sdb<br />
lrwxrwxrwx 1 root root 10 Feb 12 10:11 usb-Generic_STORAGE_DEVICE_000000014583-0:0-part1 -> ../../sdb1<br />
<br />
/dev/disk/by-label:<br />
total 0<br />
lrwxrwxrwx 1 root root 10 Feb 12 10:11 Keys -> ../../sdb1<br />
<br />
/dev/disk/by-path:<br />
total 0<br />
lrwxrwxrwx 1 root root 9 Feb 12 10:11 pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 -> ../../sdb<br />
lrwxrwxrwx 1 root root 10 Feb 12 10:11 pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 -> ../../sdb1<br />
<br />
/dev/disk/by-uuid:<br />
total 0<br />
lrwxrwxrwx 1 root root 10 Feb 12 10:11 baa07781-2a10-43a7-b876-c1715aba9d54 -> ../../sdb1}}<br />
<br />
'''UUID'''<br />
<br />
Using the filesystem UUID for persistent block device naming is considered very reliable. Filesystem UUIDs are stored in the filesystem itself, meaning that the UUID will be the same if you plug it into any other computer, and that a dd backup of it will always have the same UUID since dd does a bitwise copy.<br />
<br />
The right device node for what is now {{ic|/dev/sdb1}} will always get symlinked by {{ic|/dev/disk/by-uuid/baa07781-2a10-43a7-b876-c1715aba9d54}}. Symlinks can be used in the bootloaders "cryptkey" kernel option or anywhere else.<br />
<br />
For legacy filesystems like FAT the UUID will be much shorter but collision is still unlikely to happen if not mounting many different FAT filesystems at once.<br />
<br />
'''Label'''<br />
<br />
In the following example a FAT partition is labeled as "Keys" and will always get symlinked by {{ic|/dev/disk/by-label/Keys}}:<br />
<br />
#mkdosfs -n >volume-name< /dev/sdb1<br />
<br />
{{hc|#blkid -o list|<br />
device fs_type label mount point UUID<br />
<nowiki>-------------------------------------------------------</nowiki><br />
/dev/sdb1 vfat Keys (not mounted) 221E-09C0}}<br />
<br />
{{Note|If you plan to store the keyfile between [[#Storing_the_key_between_MBR_and_1st_partition|MBR and the 1st partition]] you '''cannot use this method''', since it only allows access to the partitions ({{ic|sdb1}}, {{ic|sdb2}}, ...) but not to the USB device ({{ic|sdb}}) itself. Use something like {{ic|/dev/disk/by-id/*}} or alternatively create a udev rule as described in the following section.}}<br />
<br />
=====Persistent udev rule=====<br />
Optionally you may choose to set up your flash drive with a [[udev]] rule. There is some documentation in the Arch wiki about that already; if you want more in-depth, structural info, read [http://reactivated.net/writing_udev_rules.html this guide]. Here is quickly how it goes.<br />
<br />
Get the serial number from your USB flash drive:<br />
lsusb -v | grep -A 5 Vendor<br />
<br />
Create a udev rule for it by adding the following to a file in {{ic|/etc/udev/rules.d/}}, such as {{ic|8-usbstick.rules}}:<br />
KERNEL=="sd*", ATTRS{serial}=="$SERIAL", SYMLINK+="$SYMLINK%n"<br />
<br />
Replace {{ic|$SYMLINK}} and {{ic|$SERIAL}} with their respective values. {{ic|%n}} will expand to the partition (just like sda is subdivided into sda1, sda2, ...). You do not need to go with the 'serial' attribute. If you have a custom rule of your own, you can put it in as well (e.g. using the vendor name).<br />
<br />
Rescan your sysfs:<br />
udevadm trigger<br />
Now check the contents of {{ic|/dev}}:<br />
ls /dev<br />
It should show your device with your desired name.<br />
<br />
==== Generating the keyfile ====<br />
Optionally you can mount a tmpfs for storing the temporary keyfile.<br />
# mkdir ./mytmpfs<br />
# mount tmpfs ./mytmpfs -t tmpfs -o size=32m<br />
# cd ./mytmpfs<br />
The advantage is that it resides in RAM and not on a physical disk, so after unmounting your keyfile is securly gone.<br />
So copy your keyfile to some place you consider as secure before unmounting.<br />
If you are planning to store the keyfile as a plain file on your USB device, you can also simply execute the following command in the corresponding directory, e.g. {{ic|/media/sdb1}}<br />
<br />
The keyfile can be of arbitrary content and size. We will generate a random temporary keyfile of 2048 bytes:<br />
# dd if=/dev/urandom of=secretkey bs=512 count=4<br />
<br />
If you stored your temporary keyfile on a physical storage device, remember to not just (re)move the keyfile later on, but use something like<br />
cp secretkey /destination/path<br />
shred --remove --zero secretkey<br />
to securely overwrite it. For overaged filesystems like FAT or ext2 this will suffice while in the case of journaling filesystems, flash memory hardware and other cases it is highly recommended to [[Securely wipe disk|wipe the entire device]] or at least the keyfiles partition.<br />
<br />
Add a keyslot for the temporary keyfile to the LUKS header:<br />
{{hc|# cryptsetup luksAddKey /dev/sda2 secretkey|<br />
Enter any LUKS passphrase:<br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
==== Storing the keyfile ====<br />
To store the key file, you have two options. The first is less risky than the other, but perhaps a bit more secure (if you consider security by obscurity as more secure).<br />
In any case you have to do some further configuration, if not already done above.<br />
<br />
==== Configuration of initcpio ====<br />
You have to add two extra modules in your {{ic|/etc/mkinitcpio.conf}}, one for the drive's file system and one for the codepage. Further if you created a udev rule, you should tell {{ic|mkinitcpio}} about it:<br />
MODULES="ata_generic ata_piix nls_cp437 vfat"<br />
FILES="/etc/udev/rules.d/8-usbstick.rules"<br />
In this example it is assumed that you use a FAT formatted USB drive. Replace those module names if you use another file system on your USB stick (e.g. ext2) or another codepage. Users running the stock Arch kernel should stick to the codepage mentioned here.<br />
<br />
If you have a non-US keyboard, it might prove useful to load your keyboard layout before you are prompted to enter the password to unlock the root partition at boot. For this, you will need the {{ic|keymap}} hook before {{ic|encrypt}}.<br />
<br />
Generate a new image (maybe you should backup a copy of your old {{ic|/boot/initramfs-linux.img}} first):<br />
# mkinitcpio -p linux<br />
<br />
==== Storing the key as a plain (visible) file ====<br />
Be sure to choose a plain name for your key &ndash; a bit of 'security through obscurity' is always nice ;-). Avoid using dotfiles (hidden files) &ndash; the {{ic|encrypt}} hook will fail to find the keyfile during the boot process.<br />
<br />
You have to add {{ic|1=cryptdevice=/dev/sda3:root cryptkey=/dev/usbstick:vfat:/secretkey}} to your [[kernel parameters]]. This assumes {{ic|/dev/usbstick}} is the FAT partition of your choice. Replace it with {{ic|/dev/disk/by-...}} or whatever your device is.<br />
<br />
That is all, reboot and have fun!<br />
<br />
==== Storing the key between MBR and 1st partition ====<br />
We will write the key directly between the Master Boot Record (MBR) and the first partition.<br />
<br />
{{Warning|You should only follow this step if you know what you are doing -- '''it can cause data loss and damage your partitions or MBR on the stick!'''}}<br />
<br />
{{Out of date|[[GRUB Legacy]] is not available anymore and for [[GRUB]] a 1-2MB gap between MBR and the beginning of other written data (e.g. first partition or LUKS-key) is needed for embedding GRUB's {{ic|core.img}}. Information regarding GPT and/or UEFI combinations are required. GRUB has changed parsing configuration.}}<br />
<br />
If you have a bootloader installed on your drive you have to adjust the values. E.g. [[GRUB]] needs the first 16 sectors (actually, it depends on the type of the file system, so do not rely on this too much), so you would have to replace {{ic|seek<nowiki>=</nowiki>4}} with {{ic|seek<nowiki>=</nowiki>16}}; otherwise you would overwrite parts of your GRUB installation. When in doubt, take a look at the first 64 sectors of your drive and decide on your own where to place your key. <br />
<br />
''Optional''<br />
If you do not know if you have enough free space before the first partition, you can do<br />
dd if=/dev/usbstick of=64sectors bs=512 count=64 # gives you copy of your first 64 sectors<br />
hexcurse 64sectors # determine free space<br />
xxd 64sectors | less # alternative hex viewer<br />
<br />
Write your key to the disk:<br />
dd if=secretkey of=/dev/usbstick bs=512 seek=4<br />
<br />
If everything went fine you can now overwrite and delete your temporary secretkey as noted above.<br />
You should not simply use {{ic|rm}} as the keyfile would only be unlinked from your filesystem and be left physically intact.<br />
<br />
Now you have to add a kernel parameter in your {{ic|/boot/grub/menu.lst}} file (GRUB); it should look something like this:<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda3:root root=/dev/mapper/root ro cryptkey=/dev/usb:2048:2048<br />
Format for the {{ic|cryptkey}} option:<br />
cryptkey=BLOCKDEVICE:OFFSET:SIZE<br />
{{ic|OFFSET}} and {{ic|SIZE}} match in this example, but this is just coincidence - they can differ (and often will). An other possible example could be<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda3:root root=/dev/mapper/root ro cryptkey=/dev/usb:8192:2048<br />
That is all, reboot and have fun! And look if your partitions still work after that ;-).<br />
<br />
=== Encrypting the Swap partition ===<br />
<br />
==== Without suspend-to-disk support ====<br />
<br />
In systems where suspend to disk is not a desired feature, it is possible to create a swap file that will have a random master key with each boot. This is accomplished by using dm-crypt directly without LUKS extensions.<br />
<br />
The {{ic|/etc/crypttab}} is well commented and you can basically just uncomment the swap line and change <device> to a persistent symlink.<br />
<br />
{{hc|/etc/crypttab|# <name> <device> <password> <options><br />
# swap /dev/hdx4 /dev/urandom <nowiki>swap,cipher=aes-cbc-essiv:sha256,size=256</nowiki>}}<br />
<br />
Where:<br />
; <name>: Represents the name ({{ic|/dev/mapper/<name>}}) to list in /etc/fstab.<br />
; <device>: Should be the symlink to the actual partition's device file.<br />
; <password>: {{ic|/dev/urandom}} sets the dm-crypt master key to be randomized on every volume recreation.<br />
; <options>: The {{ic|swap}} option runs mkswap after cryptographic's are setup.<br />
<br />
{{Warning|You should use persistent block device naming (in example ID's) for <device> because if there are multiple hard drives installed in the system, their naming order (sda, sdb,...) can occasionally be scrambled upon boot and thus the swap would be created over a valuable file system, destroying its content.}}<br />
<br />
Persistent block device naming is implemented with simple symlinks. Using UUID's or filesystem-labels is not possible as plain dm-crypt writes only encrypted data without a persistent header like LUKS. If you are not familar with one of the directories under {{ic|/dev/disk/}} read on in the section on [[#Preparation for Persistent block device naming]]<br />
<br />
{{hc|#ls -l <nowiki>/dev/disk/*/* |</nowiki> grep sda2|<br />
lrwxrwxrwx 1 root root 10 Oct 12 16:54 /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part2 -> ../../sda2}}<br />
<br />
Example line for the {{ic|/dev/sda2}} symlink from above:<br />
<br />
{{hc|/etc/crypttab|# <name> <device> <password> <options><br />
swap /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part2 /dev/urandom <nowiki>swap,cipher=aes-cbc-essiv:sha256,size=256</nowiki>}}<br />
<br />
This will map {{ic|/dev/sda2}} to {{ic|/dev/mapper/swap}} as a swap partition that can be added in {{ic|/etc/fstab}} like a normal swap.<br />
<br />
If the partition chosen for swap was previously a LUKS partition, crypttab will not overwrite the partition to create a swap partition. This is a safety measure to prevent data loss from accidental mis-identification of the swap partition in crypttab. In order to use such a partition the [[#Wipe_LUKS_header|LUKS header must be overwritten]] once.<br />
<br />
==== With suspend-to-disk support ====<br />
<br />
To be able to resume after suspending the computer to disk (hibernate), it is required to keep the swap filesystem intact. Therefore, it is required to have a pre-existent LUKS swap partition, which can be stored on the disk or input manually at startup. Because the resume takes place before {{ic|/etc/crypttab}} can be used, it is required to create a hook in {{ic|/etc/mkinitcpio.conf}} to open the swap LUKS device before resuming.<br />
<br />
If you want to use a partition which is currently used by the system, you have to disable it first:<br />
# swapoff /dev/<device><br />
<br />
Also make sure you remove any line in {{ic|/etc/crypttab}} pointing to this device.<br />
<br />
A simple way to realize encrypted swap with suspend-to-disk support is by using [[LVM]] ontop the encryption layer, so one encrypted partition can contain infinite filesystems (root, swap, home, ...). Follow the instructions on [[#Encrypting a LVM setup]].<br />
<br />
The following setup has the disadvantage of having to insert an additional passphrase for the swap partition manually on every boot.<br />
<br />
{{Warning|Do not use this setup with a key file. Please read about the issue reported [[Talk:System Encryption with LUKS for dm-crypt#Suspend to disk instructions are insecure|here]]}}<br />
<br />
To format the encrypted container for the swap partition, follow steps similar to those described in [[#Configuring LUKS]] above and create keyslot for a user-memorizable passphrase.<br />
<br />
Open the partition in {{ic|/dev/mapper}}:<br />
# cryptsetup luksOpen /dev/<device> swapDevice<br />
<br />
Create a swap filesystem inside the mapped partition:<br />
# mkswap /dev/mapper/swapDevice<br />
<br />
Now you have to create a hook to open the swap at boot time.<br />
<br />
* Create a hook file containing the open command:<br />
<br />
{{hc|/lib/initcpio/hooks/openswap|<nowiki><br />
# vim: set ft=sh:<br />
run_hook ()<br />
{<br />
cryptsetup luksOpen /dev/<device> swapDevice<br />
}<br />
</nowiki>}}<br />
<br />
for opening the swap device by typing your password or<br />
<br />
{{hc|/lib/initcpio/hooks/openswap|<nowiki><br />
# vim: set ft=sh:<br />
run_hook ()<br />
{<br />
mkdir crypto_key_device<br />
mount /dev/mapper/<root-device> crypto_key_device<br />
cryptsetup luksOpen --key-file crypto_key_device/<path-to-the-key> /dev/<device> swapDevice<br />
umount crypto_key_device<br />
}<br />
</nowiki>}}<br />
<br />
for opening the swap device by loading a keyfile from a crypted root device<br />
<br />
{{Note|If swap is on a Solid State Disk (SSD) and Discard/TRIM is desired the option {{ic|--allow-discards}} has to get added to the cryptsetup line in the openswap hook above. See [[#Discard.2FTRIM_support_for_solid_state_disks_.28SSD.29|Discard/TRIM support for solid state disks (SSD)]] or [[SSD]] for more information on discard. Additionally you have to add the mount option 'discard' to your fstab entry for the swap device.''}}<br />
<br />
* Then create and edit the hook setup file:<br />
{{hc|/lib/initcpio/install/openswap|<nowiki><br />
# vim: set ft=sh:<br />
build ()<br />
{<br />
add_runscript<br />
}<br />
help ()<br />
{<br />
cat<<HELPEOF<br />
This opens the swap encrypted partition /dev/<device> in /dev/mapper/swapDevice<br />
HELPEOF<br />
}<br />
</nowiki>}}<br />
<br />
* Add the hook {{ic|openswap}} in the {{ic|HOOKS}} array in {{ic|/etc/mkinitcpio.conf}}, before {{ic|filesystem}} but after {{ic|encrypt}}. Do not forget to add the {{ic|resume}} hook after {{ic|openswap}}.<br />
<nowiki>HOOKS="... encrypt openswap resume filesystems ..."</nowiki><br />
* Regenerate the boot image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
* Add the mapped partition to {{ic|/etc/fstab}} by adding the following line:<br />
/dev/mapper/swapDevice swap swap defaults 0 0<br />
<br />
* Set up your system to resume from {{ic|/dev/mapper/swapDevice}}. For example, if you use [[GRUB]] with kernel hibernation support, add {{ic|resume<nowiki>=</nowiki>/dev/mapper/swapDevice}} to the kernel line in {{ic|/boot/grub/grub.cfg}}. A line with encrypted root and swap partitions can look like this:<br />
<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice root=/dev/mapper/rootDevice resume=/dev/mapper/swapDevice ro<br />
<br />
To make the parameter persistent on kernel updates, add it to {{ic|/etc/default/grub}}. <br />
<br />
At boot time, the {{ic|openswap}} hook will open the swap partition so the kernel resume may use it. If you use special hooks for resuming from hibernation, make sure they are placed '''after''' {{ic|openswap}} in the {{ic|HOOKS}} array. Please note that because of initrd opening swap, there is no entry for swapDevice in {{ic|/etc/crypttab}} needed in this case.<br />
<br />
==== Using a swap file for suspend-to-disk support ====<br />
A swap file can be used to reserve swap-space within an existing partition and may also be setup inside an encrypted blockdevice's partition. When resuming from a swapfile the {{ic|resume}} hook must be supplied with the passphrase to unlock the device where the swap file is located. To create it: <br />
* Choose a mapped partition (e.g. {{ic|/dev/mapper/rootDevice}}) whose mounted filesystem (e.g. {{ic|/}}) contains enough free space to create a swapfile with the desired size. <br />
<br />
* [[HOW_TO:_Create_swap_file#Swap_file_creation | Create the swap file]] (e.g. {{ic|/swapfile}}) inside the mounted filesystem of your chosen mapped partition. Be sure to activate it with {{ic|swapon}} and also add it to your {{ic|/etc/fstab}} file afterward.<br />
<br />
* Set up your system to resume from your chosen mapped partition. For example, if you use [[GRUB]] with kernel hibernation support, add {{ic|resume<nowiki>=</nowiki>}}''your chosen mapped partition'' and {{ic|resume_offset<nowiki>=</nowiki>}}''see calculation command below'' to the kernel line in {{ic|/boot/grub/grub.cfg}}. A line with encrypted root partition can look like this:<br />
<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice resume=/dev/mapper/rootDevice resume_offset=123456789 ro<br />
<br />
The {{ic|resume_offset}} of the swap-file points to the start (extent zero) of the file and can be identified like this:<br />
<br />
# filefrag -v /swapfile | awk '{if($1==0){print $3}}'<br />
<br />
* Add the {{ic|resume}} hook to your {{ic|etc/mkinitcpio.conf}} file and [[Mkinitcpio#Image_creation_and_activation|rebuild the image]] afterward:<br />
<br />
HOOKS="... encrypt '''resume''' ... filesystems ..."<br />
<br />
* If you use a USB keyboard to enter your decryption password, then the {{ic|keyboard}} module '''must''' appear in front of the {{ic|encrypt}} hook, as shown below. Otherwise, you will not be able to boot your computer because you couldn't enter your decryption password to decrypt your Linux root partition!<br />
<br />
HOOKS="... '''keyboard''' encrypt ..."<br />
<br />
== Installing the system ==<br />
<br />
{{Note | Most of the installation can be carried out normally. However, there are a few areas where it is important to make certain selections. These are marked below.}}<br />
<br />
=== Prepare hard drive for Arch Install Scripts ===<br />
<br />
This assumes you want to install an encrypted system with the Arch Install Scripts, have created partitions for {{ic|/}} (e.g. {{ic|/dev/sdaX}}) and {{ic|/boot}} ({{ic|/dev/sdaY}}) at least, following the [[Installation_Guide|Installation Guide]] and deciding against [[LUKS#LVM:_Logical_Volume_Manager|using LVM]]. Prior to creating the partitions you have done a [[LUKS#Secure_erasure_of_the_hard_disk_drive|preparation]] of the disk for encryption according to your necessities (the necessary tools are on the installation-ISO). <br />
<br />
First check, if the blockdevice mapper {{ic|dm_mod}} is loaded with <br />
# lsmod | grep mod <br />
If one wants to use the default LUKS-cipher algorithm, there is no need to specify one for the luksFormat. You may want to check the [[LUKS#Using_LUKS_to_Format_Partitions_with_a_Passphrase|defaults]] used by the cryptsetup version at time of installation and decide yourself. With defaults a dm-crypt/LUKS blockdevice for the crypted root can be created <br />
# cryptsetup -y -v luksFormat /dev/sdaX<br />
opened<br />
# cryptsetup open /dev/sdaX cryptroot<br />
formatted with your desired filesystem<br />
# mkfs -t ext4 /dev/mapper/cryptroot<br />
and mounted<br />
# mount -t ext4 /dev/mapper/cryptroot /mnt<br />
<br />
At this point, just before installing the base system, it might be useful to check the mapping works as intended:<br />
# umount /mnt<br />
# cryptsetup close cryptroot<br />
and mount it again to check.<br />
<br />
If you created a separate {{ic|/home}} partition, the steps have to be adapted and repeated for that.<br />
What you do have to setup is a non-encrypted {{ic|/boot}} partition, which is needed for a crypted root. For a standard [[EFI|MBR/non-EFI]] {{ic|/boot}} partition that may be achieved by formatting<br />
# mkfs -t ext2 /dev/sdaY<br />
creating a mount-point for installation<br />
# mkdir /mnt/boot<br />
and mounting it<br />
# mount -t ext2 /dev/sdaY /mnt/boot<br />
<br />
That is basically what is necessary at this point before installing the base system with the [[Installation_Guide#Mount_the_partitions|Arch Install Scripts]]. Take care to install the bootloader to {{ic|/mnt/boot}} with the {{ic|pacstrap}} script. Additional configuration steps must be followed before booting the installed system.<br />
<br />
=== Configure initramfs ===<br />
One important point is to add the hooks relevant for your particular install in the correct order to {{ic|/etc/mkinitcpio.conf}}. The one you ''have'' to add when encrypting the root filesystem is {{ic|encrypt}}. A recommended hook for LUKS encrypted blockdevices is {{ic|shutdown}} to ensure controlled unmounting during system shutdown. Others needed, e.g. {{ic|keymap}}, should be clear from other manual steps you follow during the installation and further details in the following. For detailed information about initramfs configuration and available Hooks refer to [[Mkinitcpio#HOOKS]].<br />
<br />
{{Note|The {{ic|encrypt}} hook is only needed if your '''root''' partition is a ''LUKS'' partition (or a LUKS partition that needs to be mounted ''before'' root). The {{ic|encrypt}} hook is not needed for any other encrypted partitions (swap, for example). System initialization scripts ({{ic|/etc/rc.sysinit}} and {{ic|/etc/crypttab}} among others) take care of those.}}<br />
<br />
It is important that the {{ic|encrypt}} hook comes ''before'' the {{ic|filesystems}} hook (in case you are using '''LVM on LUKS''', the order should be: {{ic|encrypt lvm2 filesystems}}), so make sure that your {{ic|HOOKS}} array looks something like this:<br />
{{hc|etc/mkinitcpio.conf|HOOKS<nowiki>=</nowiki>"(base udev) ... '''encrypt''' ... filesystems ..."}}<br />
<br />
If you need support for foreign keymaps for your encryption password, you have to specify the hook {{ic|keymap}} as well before {{ic|encrypt}}.<br />
<br />
If you have a USB keyboard, you will need the {{ic|keyboard}} hook. Without it, no USB keyboard will work in early userspace.<br />
<br />
In the same file, you may want to add to "MODULES" '''dm_mod''' and the filesystem types used, e.g: {{ic|MODULES<nowiki>=</nowiki>"dm_mod ext4"}}<br />
<br />
After you are done don't forget:<br />
mkinitcpio -p linux<br />
<br />
<br />
=== Kernel parameter configuration of the bootloader ===<br />
In order to enable booting an encrypted root partition, it is passed to the {{ic|encrypt}} hook with [[kernel parameters]] to be set up in the bootloader. <br />
The main parameter is '''cryptdevice''', with the following syntax:<br />
cryptdevice=<device>:<dmname><br />
; <device>: The path to the raw encrypted device. Usage of [[Persistent block device naming]] is advisable.<br />
; <dmname>: The name given to the device after decryption, will be available as {{ic|/dev/mapper/<dmname>}}. (<dmname> '''MUST NOT''' be set to a name already used for LVM partitions!)<br />
<br />
So if the encrypted root device in the example is {{ic|/dev/sda2}} and the decrypted one should be mapped to {{ic|/dev/mapper/cryptroot}}, the kernel parameter would be:<br />
cryptdevice=/dev/sda2:cryptroot<br />
This will make the system prompt for the passphrase to unlock the root device on a cold boot. <br />
<br />
Depending on the setup other parameters are required as well:<br />
cryptdevice=<device>:<dmname> root=<device> resume=<device> cryptkey=<device>:<fstype>:<path><br />
<br />
; root=<device>: The device file of the actual (decrypted) root filesystem. If the filesystem is formatted directly on the decrypted device file this will be {{ic|/dev/mapper/<dmname>}}. If LVM is used, the device must be addressed like {{ic|/dev/mapper/<volgroup>-<pvol>}} or {{ic|/dev/<volgroup>/<pvol>}}.<br />
; resume=<device>: The device file of the decrypted (swap) filesystem used for suspend2disk.<br />
; cryptkey=<nowiki><device>:<fstype>:<path></nowiki>: Required for reading a [[#Storing_the_Key_File|keyfile]] from a filesystem.<br />
<br />
The syntax for the optional '''cryptkey''' parameter is:<br />
<br />
cryptkey=<device>:<fstype>:<path><br />
<br />
; <device>: The raw block device where the key exists.<br />
; <fstype>: The filesystem type of <device> (or auto).<br />
; <path>: The absolute path of the keyfile within the device.<br />
<br />
Examples on configuration for [[GRUB#Root Encryption|GRUB]] and [[Syslinux#Basic Config|Syslinux]] are available on the respective pages.<br />
<br />
=== Fstab ===<br />
Further, double-check the {{ic|gen[[fstab]]}} scripts result for your {{ic|/dev/mapper/cryptroot}} and other mounts.<br />
<br />
=== AIF Instructions ===<br />
{{Deletion|}}<br />
{{Out of date|AIF (Arch Installation Framework; referenced below also as {{ic|/arch/setup}}) does not exist anymore, GRUB Legacy is not available anymore}}<br />
==== Prepare hard drive for AIF ====<br />
<br />
Now that {{ic|/dev/mapper/root}} and {{ic|/dev/mapper/home}} are in place, we can enter the regular Arch setup script to install the system into the encrypted volumes.<br />
# /arch/setup<br />
Skip the Partitioning and Auto-Prepare steps and go straight to manual configuration.<br />
Instead of choosing the hardware devices ({{ic|/dev/sdaX}}) directly, you have to select the mapper devices created above.<br />
Choose {{ic|/dev/mapper/root}} for your root and {{ic|/dev/mapper/home}} as {{ic|/home}} partition respectively and format them with any filesystem you like.<br />
The same is valid for a swap partition which is set up like the {{ic|/home}} partition. Make sure you mount {{ic|/dev/sda1}} as the {{ic|/boot}} partition, or else the installer will not properly set up the bootloader.<br />
<br />
==== Select and Install packages ====<br />
Select and install the packages as usual: the base package contains all required programs.<br />
<br />
==== Exit Install ====<br />
Now that the install is finished the only thing left to do is add entries to the {{ic|/etc/crypttab}} file so you do not have to enter the passphrase for all encrypted partitions. This works only for non-root partitions e.g. {{ic|/home}}, swap, etc.<br />
# vi /mnt/etc/crypttab<br />
<br />
Add one of the following for the {{ic|/home}} partition.<br />
{{Note|Using a passphrase to decrypt LUKS partitions automatically from {{ic|/etc/crypttab}} is deprecated: see http://www.mail-archive.com/arch-projects@archlinux.org/msg02115.html}}<br />
home /dev/sda5 /etc/mypassword1<br />
<br />
You can also use a keyfile instead of a passphrase. If not already done, create a keyfile and add the key to the corresponding LUKS partition as described [[#Adding_Additional_Passphrases_or_Keyfiles_to_a_LUKS_Encrypted_Partition|above]].<br />
Then add the following information to the {{ic|/etc/crypttab}} file for automounting:<br />
home /dev/sda5 /path/of/your/keyfile<br />
<br />
If you used a USB device to store your keyfile, you should have something like this:<br />
home /dev/sda5 /dev/sd*1/keyfile<br />
<br />
Or if the keyfile was stored in the MBR, it should be like this:<br />
home /dev/sda5 /dev/sd*:2048:2048<br />
<br />
{{Box BLUE|Note:|When reading the keyfile from the MBR it should be {{ic|/dev/sdb}} not {{ic|/dev/sdb1}} but if the key is in the filesystem it should still be {{ic|/dev/sdb1}}.}}<br />
<br />
After rebooting you should now be presented with the text<br />
A password is required to access the root filesystem:<br />
followed by a prompt for a LUKS password. Type it in and everything should boot.<br />
Once you have logged in, have a look at your mounted partitions by typing {{ic|mount}}. You should have {{ic|/dev/mapper/root}} mounted at {{ic|/}} and, if you set up a separate encrypted home partition, {{ic|/dev/mapper/home}} mounted at {{ic|/home}}. If you set up encrypted swap, {{ic|swapon -s}} should have {{ic|/dev/mapper/swap}} listed as your swap partition.<br />
<br />
{{Note|Eventually the text prompting for the password is mixed up with other boot messages. So the boot process may seem frozen at first glance, but it is not, simply enter your password and press {{keypress|Enter}}.}}<br />
<br />
==== GRUB Legacy ====<br />
{{Out of date|Like AIF in this section, GRUB Legacy and LILO are dropped. }}<br />
'''[[GRUB Legacy]]:''' You have to make some small changes to the entries generated by the installer by replacing {{ic|/dev/mapper/root}} with {{ic|/dev/sda3}}. The important point to remember here is to use the same {{ic|cryptdevice}} name you assigned when you initially unlocked your device. In this example, the device name is {{ic|cryptroot}}; customize yours accordingly:<br />
<br />
# (0) Arch Linux<br />
title Arch Linux<br />
root (hd0,0)<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda3:cryptroot root=/dev/mapper/cryptroot ro<br />
initrd /initramfs-linux.img<br />
<br />
For kernels older than 2.6.37, the syntax is:<br />
# (0) Arch Linux<br />
title Arch Linux<br />
root (hd0,0)<br />
kernel /vmlinuz26 root=/dev/sda3 ro<br />
initrd /kernel26.img<br />
<br />
==== LILO ====<br />
'''LILO:''' Edit the Arch Linux section in {{ic|/etc/lilo.conf}} and include a line for the {{ic|append}} option, over the initrd, with the {{ic|root<nowiki>=</nowiki>/dev/sda3}} parameter. The {{ic|append}} section makes the same kernel line as in GRUB. Also, you can omit the {{ic|root}} option above the {{ic|image}} option. The section looks like this:<br />
# Arch Linux lilo section<br />
image = /vmlinuz-linux<br />
# root = /dev/sda3<br />
label = Arch<br />
initrd = /initramfs-linux.img<br />
append = "root=/dev/sda3"<br />
read-only<br />
<br />
If you want to use a USB flash drive with a keyfile, you have to append the {{ic|cryptkey}} option. See the corresponding section above.<br />
<br />
== Remote unlocking of the root (or other) partition ==<br />
If you want to be able to reboot a fully LUKS-encrypted system remotely, or start it with a Wake-on-LAN service, you will need a way to enter a passphrase for the root partition/volume at startup. This can be achieved by running the {{ic|net}} hook along with an [[SSH]] server in initrd. Install the {{AUR|dropbear_initrd_encrypt}} package from the [[Arch User Repository|AUR]] and follow the post-installation instructions. Replace the {{ic|encrypt}} hook with {{ic|dropbear encryptssh}} in {{ic|/etc/mkinitcpio.conf}}. Put the {{ic|net}} hook early in the HOOKS array if your DHCP server takes a long time to lease IP addresses.<br />
<br />
If you would simply like a nice solution to mount other encrypted partitions (such as {{ic|/home}})remotely, you may want to look at [https://bbs.archlinux.org/viewtopic.php?pid=880484 this forum thread].<br />
<br />
== Backup the cryptheader ==<br />
If the header of your encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much as a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. A damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table.<br />
<br />
Therefore, having a backup of the headers and storing them on another disk might be a good idea.<br />
<br />
'''Attention:''' Many people recommend NOT backing up the cryptheader, but even so it's a single point of failure!<br />
In short, the problem is that LUKS is not aware of the duplicated cryptheader, which contains the master key which is used to encrypt all files on your partition. Of course this master key is encrypted with your passphrases or keyfiles.<br />
But if one of those gets compromised and you want to revoke it you have to do this on all copies of the cryptheader!<br />
I.e. if someone has got your cryptheader and one of your keys he can decrypt the master key and access all your data.<br />
Of course the same is true for all backups you create of your partions.<br />
So you decide if you are one of those paranoids brave enough to go without a backup for the sake of security or not.<br />
See also the [http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions#6._Backup_and_Data_Recovery| LUKS FAQ] for further details on this.<br />
<br />
=== Backup ===<br />
==== Using cryptsetup ====<br />
Cryptsetups {{ic|luksHeaderBackup}} action stores a binary backup of the LUKS header and keyslot area:<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /mnt/<backup>/<file>.img<br />
where <device> is the partition containing the LUKS volume.<br />
<br />
{{Note|Using {{ic|-}} as header backup file writes to a file named {{ic|-}}.}}<br />
<br />
{{Tip|You can also back up the plaintext header into ramfs and encrypt it in example with gpg before writing to persistent backup storage by executing the following commands.}}<br />
{{bc|# mkdir /root/<tmp>/<br />
# mount ramfs /root/<tmp>/ -t ramfs<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /root/<tmp>/<file>.img<br />
# gpg2 --recipient <User ID> --encrypt /root/<tmp>/<file>.img <br />
# cp /root/<tmp>/<file>.img.gpg /mnt/<backup>/<br />
# umount /root/<tmp>}}<br />
{{Warning|Tmpfs can swap to harddisk if low on memory so it is not recommended here.}}<br />
<br />
==== Manually ====<br />
First you have to find out the payload offset of the crypted partition:<br />
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki> grep "Payload offset"|<br />
Payload offset: 4040}}<br />
Second check the sector size of the drive<br />
{{hc|# fdisk -l /dev/<device> <nowiki>|</nowiki>grep "Sector size"|Sector size (logical/physical): 512 bytes / 512 bytes}}<br />
<br />
Now that you know the values, you can backup the header with a simple dd command:<br />
# dd if=/dev/<device> of=/path/to/<file>.img bs=512 count=4040<br />
and store it safely.<br />
<br />
=== Restore ===<br />
Be careful before restore: make sure that you chose the right partition (again replace sdaX with the corresponding partition).<br />
Restoring the wrong header or restoring to an unencrypted partition will cause data loss.<br />
<br />
==== Using cryptsetup ====<br />
Or you can use the luksHeaderRestore command:<br />
cryptsetup luksHeaderRestore /dev/sdaX --header-backup-file ./backup.img<br />
<br />
'''Note:''' All the keyslot areas are overwritten; only active keyslots from the backup file are available after issuing this command.<br />
<br />
==== Manually ====<br />
Again, you will need to the same values as when backing up:<br />
dd if=./backup.img of=/dev/sdX bs=512 count=4040<br />
<br />
== Encrypting a loopback filesystem ==<br />
''[This paragraph has been merged from another page; its consistency with the other paragraphs should be improved]''<br />
<br />
=== Preparation and mapping ===<br />
First, start by creating an encrypted container!<br />
<br />
dd if=/dev/urandom of=/bigsecret bs=1M count=10<br />
<br />
This will create the file {{ic|bigsecret}} with a size of 10 megabytes.<br />
<br />
losetup /dev/loop0 /bigsecret<br />
<br />
This will create the device node {{ic|/dev/loop0}}, so that we can mount/use our container.<br />
<br />
{{Note|If it gives you the error {{ic|/dev/loop0: No such file or directory}}, you need to first load the kernel module with {{ic|modprobe loop}}. These days (Kernel 3.2) loop devices are created on demand. Ask for a new loop device with {{ic|losetup -f}}.}}<br />
<br />
cryptsetup luksFormat /dev/loop0<br />
<br />
This will ask you for a password for your new container file.<br />
<br />
{{Note|If you get an error like {{ic|Command failed: Failed to setup dm-crypt key mapping. Check kernel for support for the aes-cbc-essiv:sha256 cipher spec and verify that /dev/loop0 contains at least 133 sectors|}}, then run {{ic|modprobe dm-mod}}.}}<br />
<br />
cryptsetup luksOpen /dev/loop0 secret<br />
<br />
The encrypted container is now available through the device file {{ic|/dev/mapper/secret}}.<br />
Now we are able to create a partition in the container:<br />
<br />
mkfs.ext2 /dev/mapper/secret<br />
<br />
and mount it...<br />
<br />
mkdir /mnt/secret<br />
mount -t ext2 /dev/mapper/secret /mnt/secret<br />
<br />
We can now use the container as if it was a normal partition!<br />
To unmount the container:<br />
<br />
umount /mnt/secret<br />
cryptsetup luksClose secret<br />
losetup -d /dev/loop0 # free the loopdevice.<br />
<br />
so, if you want to mount the container again, you just apply the following commands:<br />
<br />
losetup /dev/loop0 /bigsecret<br />
cryptsetup luksOpen /dev/loop0 secret<br />
mount -t ext2 /dev/mapper/secret /mnt/secret<br />
<br />
=== Encrypt using a key-file ===<br />
Let us first generate a 2048 byte random keyfile:<br />
<br />
dd if=/dev/urandom of=keyfile bs=1k count=2<br />
<br />
We can now format our container using this key<br />
<br />
cryptsetup luksFormat /dev/loop0 keyfile<br />
<br />
or our partition : <br />
<br />
cryptsetup luksFormat /dev/hda2 keyfile<br />
<br />
Once formatted, we can now open the LUKS device using the key:<br />
<br />
cryptsetup -d keyfile luksOpen /dev/loop0 container<br />
<br />
You can now like before format the device {{ic|/dev/mapper/container}} with your favorite filesystem and then mount it just as easily.<br />
<br />
The keyfile is now the only key to your file. I personally advise encrypting your keyfile using your private GPG key and storing an off-site secured copy of the file.<br />
<br />
=== Resizing the loopback filesystem ===<br />
First we should unmount the encrypted container:<br />
umount /mnt/secret<br />
cryptsetup luksClose secret<br />
losetup -d /dev/loop0 # free the loopdevice.<br />
<br />
After this we need to expand our container file with the size of the data we want to add:<br />
<br />
dd if=/dev/urandom bs=1M count=1024 | cat - >> /bigsecret<br />
<br />
Be careful to really use TWO {{ic|>}}, or you will override your current container!<br />
<br />
You could use {{ic|/dev/zero}} instead of {{ic|/dev/urandom}} to significantly speed up the process, but with {{ic|/dev/zero}} your encrypted filesystems will ''not be as secure''. (A better option to create random data quicker than {{ic|/dev/urandom}} is {{ic|frandom}} [https://aur.archlinux.org/packages.php?ID=9869], available from the [[AUR]]).<br />
A faster (almost instant) method than dd is {{ic|truncate}} , but its use has the same security implications as using /dev/zero. The size passed to truncate is the final size to make the file, so don't use a value less than that of the current file or you will lose data. e.g. to increase a 20G file by 10G: truncate -s 30G filename.<br />
<br />
Now we have to map the container to the loop device:<br />
losetup /dev/loop0 /bigsecret<br />
cryptsetup luksOpen /dev/loop0 secret<br />
After this we will resize the encrypted part of the container to the maximum size of the container file:<br />
cryptsetup resize secret<br />
Finally, we can resize the filesystem. Here is an example for ext2/3/4:<br />
e2fsck -f /dev/mapper/secret # Just doing a filesystem check, because it's a bad idea to resize a broken fs<br />
resize2fs /dev/mapper/secret<br />
You can now mount your container again:<br />
mount /dev/mapper/secret /mnt/secret<br />
<br />
== Encrypting a LVM setup ==<br />
{{Merge|Encrypted_LVM |Device mapper stacking is explained there building on the LVM wiki with a howto for both approaches below.}}<br />
<br />
It's really easy to use encryption with [[LVM]]. If you do not know how to set up LVM, then read [[Installing with Software RAID or LVM]].<br />
<br />
'''LVM on LUKS'''<br />
<br />
The easiest and best method is to set up LVM on top of the encrypted partition instead of the other way round. This link here is easy to follow and explains everything: [http://www.pindarsign.de/webblog/?p=767 Arch Linux: LVM on top of an encrypted partition]<br />
<br />
The most important thing in setting LVM on '''top''' of encryption is to [[#Configure initramfs|configure the initramfs]] for running the {{ic|encrypt}} hook '''before''' the {{ic|lvm2}} hook (and those two before the {{ic|filesystems}} hook). <br />
<br />
'''LUKS on LVM'''<br />
<br />
To use encryption on top of LVM, you have to first set up your LVM volumes and then use them as the base for the encrypted partitions. That means, in short, that you have to set up LVM first. Then follow this guide, but replace all occurrences of {{ic|/dev/sdXy}} in the guide with its LVM counterpart. (E.g.: {{ic|/dev/sda5}} -> {{ic|/dev/<volume group name>/home}}). This is used to setup partitions (inside the LVM) which can be unlocked separately or a mixture of encrypted and non-encrypted partitions. <br />
<br />
For encrypted partitions inside an LVM, the LVM-hook has to run first, before the respective encrypted logical volumes can be unlocked. So for this add the {{ic|encrypt}} hook in {{ic|/etc/mkinitcpio.conf}} '''after''' the {{ic|lvm2}} hook, if you chose to set up encrypted partitions on '''top''' of LVM. Also remember to change {{ic|USELVM}} in {{ic|/etc/rc.conf}} to {{ic|"yes"}}. <br />
<br />
=== LVM with Arch Linux Installer (>2009.08 <2012.07.15) ===<br />
{{Out of date|As of the [https://www.archlinux.org/news/install-media-20120715-released/ 2012.07.15 installation media release] the AIF (Arch Installation Framework) and grub-legacy are dropped. These outdated instructions still give the backbones to understanding what to do. If you plan to do a fresh install, also check the howto [[Encrypted_LVM]].}}<br />
<br />
In between Arch Linux installation media release 2009.08 and 2012.07.15 LVM and dm_crypt had been supported by the installer out of the box.<br />
This made it very easy to configure a system for [[LVM]] on dm-crypt or vice versa.<br />
Actually the configuration is done exactly as without LVM: see the [[#Arch Linux Installer (>2009.08 <2012.07.15)|corresponding]] section above. It differs only in two aspects.<br />
<br />
==== The partition and filesystem choice ====<br />
Create a small, unencrypted boot partition and use the remaining space for a single partition which can later be split up into multiple logic volumes by [[LVM]].<br />
<br />
For a LVM-on-dm-crypt system set up the filesystems and mounting points for example like this:<br />
/dev/sda1 raw->ext2;yes;/boot;no_opts;no_label;no_params<br />
/dev/sda2 raw->dm_crypt;yes;no_mountpoint;no_opts;sda2crypt;-c_aes-xts-plain_-y_-s_512<br />
/dev/mapper/sda2crypt dm_crypt->lvm-vg;yes;no_mountpoint;no_opts;no_label;no_params<br />
/dev/mapper/sda2crypt+ lvm-pv->lvm-vg;yes;no_mountpoint;no_opts;cryptpool;no_params<br />
/dev/mapper/cryptpool lvm-vg(cryptpool)->lvm-lv;yes;no_mountpoint;no_opts;cryptroot;10000M|lvm-lv;yes;no_mountpoint;no_opts;crypthome;20000M<br />
/dev/mapper/cryptpool-cryptroot lvm-lv(cryptroot)->ext3;yes;/;no_opts;cryptroot;no_params<br />
/dev/mapper/cryptpool-crypthome lvm-lv(crypthome)->ext3;yes;/home;no_opts;cryptroot;no_params<br />
<br />
==== The configuration stage ====<br />
* In {{ic|/etc/mkinitcpio.conf}} add the {{ic|encrypt}} hook '''before''' the {{ic|lvm2}} hook in the {{ic|HOOKS}} array, if you set up LVM on top of the encrypted partition.<br />
<br />
That is it for the LVM & dm_crypt specific part. The rest is done as usual.<br />
<br />
{{Accuracy|The {{ic|lvm2}} hook activates the (encrypted) root volume group long before sysvinit (or systemd) can run from there. Letting sysvinit later run a second LVM activation in addition serves no purpose. Read [[LVM#Configure system]]. However this error is duplicated within the [[#Encrypting a LVM setup]] section.}}<br />
* In {{ic|/etc/rc.conf}} set {{ic|USELVM}} to {{ic|"yes"}}.<br />
<br />
=== Applying this to a non-root partition ===<br />
You might get tempted to apply all this fancy stuff to a non-root partition. Arch does not support this out of the box, however, you can easily change the cryptdev and cryptname values in {{ic|/lib/initcpio/hooks/encrypt}} (the first one to your {{ic|/dev/sd*}} partition, the second to the name you want to attribute). That should be enough.<br />
<br />
The big advantage is you can have everything automated, while setting up {{ic|/etc/crypttab}} with an external key file (i.e. the keyfile is not on any internal hard drive partition) can be a pain - you need to make sure the USB/FireWire/... device gets mounted before the encrypted partition, which means you have to change the order of {{ic|/etc/fstab}} (at least).<br />
<br />
Of course, if the {{Pkg|cryptsetup}} package gets upgraded, you will have to change this script again. However, this solution is to be preferred over hacking {{ic|/etc/rc.sysinit}} or similar files. Unlike {{ic|/etc/crypttab}}, only one partition is supported, but with some further hacking one should be able to have multiple partitions unlocked.<br />
<br />
If you want to do this on a software RAID partition, there is one more thing you need to do. Just setting the {{ic|/dev/mdX}} device in {{ic|/lib/initcpio/hooks/encrypt}} is not enough; the {{ic|encrypt}} hook will fail to find the key for some reason, and not prompt for a passphrase either. It looks like the RAID devices are not brought up until after the {{ic|encrypt}} hook is run. You can solve this by putting the RAID array in {{ic|/boot/grub/menu.lst}}, like <br />
kernel /boot/vmlinuz-linux md=1,/dev/hda5,/dev/hdb5<br />
<br />
If you set up your root partition as a RAID, you will notice the similarities with that setup ;-). [[GRUB]] can handle multiple array definitions just fine:<br />
kernel /boot/vmlinuz-linux root=/dev/md0 ro md=0,/dev/sda1,/dev/sdb1 md=1,/dev/sda5,/dev/sdb5,/dev/sdc5<br />
<br />
=== LVM and dm-crypt manually (short version) ===<br />
<br />
==== Notes ====<br />
If you are smart enough for this, you will be smart enough to ignore/replace LVM-specific things if you do not want to use LVM.<br />
<br />
{{Note|This brief uses reiserfs for some of the partitions, so change this accordingly if you want to use a more "normal" file system, like ext4.}}<br />
<br />
==== Partitioning scheme ====<br />
{{ic|/dev/sda1}} -> {{ic|/boot}}<br />
{{ic|/dev/sda2}} -> LVM<br />
<br />
==== The commands ====<br />
cryptsetup -d /dev/random -c aes-xts-plain -s 512 create lvm /dev/sda2<br />
dd if=/dev/urandom of=/dev/mapper/lvm<br />
cryptsetup remove lvm<br />
lvm pvcreate /dev/sda2<br />
lvm vgcreate lvm /dev/sda2<br />
lvm lvcreate -L 10G -n root lvm<br />
lvm lvcreate -L 500M -n swap lvm<br />
lvm lvcreate -L 500M -n tmp lvm<br />
lvm lvcreate -l 100%FREE -n home lvm<br />
cryptsetup luksFormat -c aes-xts-plain -s 512 /dev/lvm/root<br />
cryptsetup luksOpen /dev/lvm/root root<br />
mkreiserfs /dev/mapper/root<br />
mount /dev/mapper/root /mnt<br />
dd if=/dev/zero of=/dev/sda1 bs=1M<br />
mkreiserfs /dev/sda1<br />
mkdir /mnt/boot<br />
mount /dev/sda1 /mnt/boot<br />
mkdir -p -m 700 /mnt/etc/luks-keys<br />
dd if=/dev/random of=/mnt/etc/luks-keys/home bs=1 count=256<br />
<br />
==== Install Arch Linux ====<br />
Run {{ic|/arch/setup}}<br />
<br />
==== Configuration ====<br />
<br />
===== /etc/rc.conf =====<br />
Change {{ic|USELVM<nowiki>=</nowiki>"no"}} to {{ic|USELVM<nowiki>=</nowiki>"yes"}}.<br />
<br />
===== /etc/mkinitcpio.conf =====<br />
Put {{ic|lvm2}} and {{ic|encrypt}} (in that order) before {{ic|filesystems}} in the {{ic|HOOKS}} array. Again, note that you are setting encryption on '''top''' of LVM.)<br />
<br />
if you want install the system on a usb stick, you need to put {{ic|usb}} just after {{ic|udev}}.<br />
<br />
===== /boot/grub/menu.lst =====<br />
Change {{ic|root<nowiki>=</nowiki>/dev/hda3}} to {{ic|root<nowiki>=</nowiki>/dev/lvm/root}}.<br />
<br />
For kernel >= 2.6.30, you should change {{ic|root<nowiki>=</nowiki>/dev/hda3}} to the following:<br />
cryptdevice=/dev/lvm/root:root root=/dev/mapper/root<br />
<br />
if you want install the system on a usb stick, you need to add {{ic|lvmdelay<nowiki>=</nowiki>/dev/mapper/lvm-root}}<br />
<br />
===== /etc/fstab =====<br />
/dev/mapper/root / reiserfs defaults 0 1<br />
/dev/sda1 /boot reiserfs defaults 0 2<br />
/dev/mapper/tmp /tmp tmpfs defaults 0 0<br />
/dev/mapper/swap none swap sw 0 0<br />
<br />
===== /etc/crypttab =====<br />
<br />
swap /dev/lvm/swap SWAP -c aes-xts-plain -h whirlpool -s 512<br />
tmp /dev/lvm/tmp /dev/urandom -c aes-xts-plain -s 512<br />
<br />
==== After rebooting ====<br />
<br />
===== The commands =====<br />
cryptsetup luksFormat -c aes-xts-plain -s 512 /dev/lvm/home /etc/luks-keys/home<br />
cryptsetup luksOpen -d /etc/luks-keys/home /dev/lvm/home home<br />
mkreiserfs /dev/mapper/home<br />
mount /dev/mapper/home /home<br />
<br />
===== /etc/crypttab =====<br />
home /dev/lvm/home /etc/luks-keys/home<br />
<br />
===== /etc/fstab =====<br />
/dev/mapper/home /home reiserfs defaults 0 0<br />
<br />
=== / on LVM on LUKS ===<br />
Make sure your kernel command line looks like this:<br />
root=/dev/mapper/<volume-group>-<logical-volume> cryptdevice=/dev/<luks-part>:<volume-group><br />
For example:<br />
root=/dev/mapper/vg-arch cryptdevice=/dev/sda4:vg<br />
<br />
Or like this:<br />
cryptdevice=/dev/<volume-group>/<logical-volume>:root root=/dev/mapper/root<br />
<br />
==Using GPG or OpenSSL Encrypted Keyfiles==<br />
The following forum posts give instructions to use two factor authentication, gpg or openssl encrypted keyfiles, instead of a plaintext keyfile described earlier in this wiki article [https://bbs.archlinux.org/viewtopic.php?id=120243 System Encryption using LUKS with GPG encrypted keys]:<br />
* GnuPG: [https://bbs.archlinux.org/viewtopic.php?pid=943338#p943338 Post regarding GPG encrypted keys] This post has the generic instructions.<br />
* OpenSSL: [https://bbs.archlinux.org/viewtopic.php?pid=947805#p947805 Post regarding OpenSSL encrypted keys] This post only has the {{ic|ssldec}} hooks.<br />
* OpenSSL: [https://bbs.archlinux.org/viewtopic.php?id=155393 Post regarding OpenSSL salted bf-cbc encrypted keys] This post has the {{ic|bfkf}} initcpio hooks, install, and encrypted keyfile generator scripts.<br />
<br />
Note that:<br />
* You can follow the above instructions with only two primary partitions one boot partition <br />
(required because of LVM), and one primary LVM partition. Within the LVM partition you can have <br />
as many partitions as you need, but most importantly it should contain at least root, swap, and <br />
home logical volume partitions. This has the added benefit of having only one keyfile for all <br />
your partitions, and having the ability to hibernate your computer (suspend to disk) where the <br />
swap partition is encrypted. If you decide to do so your hooks in {{ic|/etc/mkinitcpio.conf}} <br />
should look like<br />
{{ic|HOOKS&#61;" ... usb usbinput (etwo or ssldec) encrypt(if using openssl) lvm2 resume ... "}}<br />
and you should add {{ic|"resume&#61;/dev/mapper/<VolumeGroupName>-<LVNameOfSwap>"}} to your [[kernel parameters]].<br />
* If you need to temporarily store the unecrypted keyfile somewhere, do not store them on an <br />
unencrytped disk. Even better make sure to store them to RAM such as {{ic|/dev/shm}}.<br />
* If you want to use a GPG encrypted keyfile, you need to use a statically compiled GnuPG version 1.4 or you could edit the hooks and use this AUR package [https://aur.archlinux.org/packages.php?ID=58030 gnupg1]<br />
* It is possible that an update to OpenSSL could break the custom {{ic|ssldec}} mentioned in the second forum post.<br />
<br />
==Securing the unencrypted boot partition==<br />
Referring to an article from the ct-magazine (Issue 3/12, page 146, 01.16.2012 http://www.heise.de/ct/inhalt/2012/03/6/) the following script checks all files under {{ic|/boot}} for changes of SHA-1 hash, inode and occupied blocks on the hard drive. It also checks the MBR.<br />
<br />
The script with installation instructions is available here: ftp://ftp.heise.de/pub/ct/listings/1203-146.zip (Author: Juergen Schmidt, ju at heisec.de; License: GPLv2). There is also an AUR package: {{AUR|chkboot}}<br />
<br />
After installation:<br />
* For classical sysvinit: add {{ic|/usr/local/bin/chkboot.sh &}} to your {{ic|/etc/rc.local}}<br />
* For systemd: add a service file and enable the service: [[systemd]]. The service file might look like:<br />
[Unit]<br />
Description=Check that boot is what we want<br />
Requires=basic.target<br />
After=basic.target<br />
<br />
[Service]<br />
Type=oneshot<br />
ExecStart=/usr/local/bin/chkboot.sh<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
<br />
There is a small caveat for systemd: At the time of writing the original {{ic|chkboot.sh}} script provided contains an empty space at the beginning of {{ic|<u> </u>#!/bin/bash}} which has to be removed for the service to start successfully.<br />
<br />
As {{ic|/usr/local/bin/chkboot_user.sh}} need to be excuted after login, add it to the autostart (e.g. under KDE -> System Settings -> Startup and Shutdown -> Autostart; Gnome3: gnome-session-properties). <br />
<br />
With Arch Linux changes to {{ic|/boot}} are pretty frequent, for example by new kernels rolling-in. Therefore it may be helpful to use the scripts with every full system update. One way to do so: <br />
<br />
#!/bin/bash<br />
#<br />
# Note: Insert your <user> and execute it with sudo for pacman & chkboot to work automagically<br />
#<br />
echo "Pacman update [1] Quickcheck before updating" & <br />
sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user> <br />
/usr/local/bin/chkboot.sh<br />
sync # sync disks with any results <br />
sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user> <br />
echo "Pacman update [2] Syncing repos for pacman" <br />
pacman -Syu<br />
/usr/local/bin/chkboot.sh<br />
sync <br />
sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user><br />
echo "Pacman update [3] All done, let's roll on ..."<br />
<br />
== Automount user homes on login ==<br />
See [[Pam mount]].<br />
<br />
== Resources ==<br />
* [http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions cryptsetup FAQ] - The main and foremost help resource, directly from the developers.<br />
* [http://www.freeotfe.org/ FreeOTFE] - Supports unlocking LUKS encrypted volumes in Microsoft Windows.<br />
<br />
<br />
{{Out of date|Explained separately for each link beneath.}}<br />
* [http://vimeo.com/40694871 Arch cryptsetup example video] - A HowTo video on setting up an encrypted Arch system from scratch. The video still shows an installation with AIF, which is at the time of writing deprecated / not developed further. The important partitioning and cryptsetup are shown outside AIF though.<br />
* [http://yannickloth.be/blog/2010/08/01/installing-archlinux-with-software-raid1-encrypted-filesystem-and-lvm2/ Install Arch Linux on top of RAID1, LVM2, and encrypted partitions] - The HowTo instructs to make a full Fedora 13 Install only to set up the mapping. Then legacy AIF is used.</div>Chehrihttps://wiki.archlinux.org/index.php?title=Dm-crypt&diff=261590Dm-crypt2013-06-06T23:55:07Z<p>Chehri: /* Creating Disk Partitions */</p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:Security]]<br />
[[Category:File systems]]<br />
[[de:ArchLinux mit verschlüsseltem LVM und Systemd]]<br />
[[fr:LUKS]]<br />
[[ru:System Encryption with LUKS]]<br />
[[zh-CN:System Encryption with LUKS]]<br />
{{Article summary start}}<br />
{{Article summary text|This tutorial will show you how to set up system encryption with LUKS for dm-crypt.}}<br />
{{Article summary heading|Related}}<br />
{{Article summary wiki|Disk Encryption}}<br />
{{Article summary wiki|Removing System Encryption}}<br />
{{Article summary end}}<br />
<br />
This article focuses on how to set up full system encryption on Arch Linux, using dm-crypt with LUKS.<br />
<br />
'''dm-crypt''' is the standard device-mapper encryption functionality provided by the Linux kernel. It can be used directly by those who like to have full control over all aspects of partition and key management.<br />
<br />
'''LUKS''' is an additional convenience layer which stores all of the needed setup information for dm-crypt on the disk itself and abstracts partition and key management in an attempt to improve ease of use.<br />
<br />
For more details on how dm-crypt+LUKS compares to other disk encryption solution, see [[Disk Encryption#Comparison table]].<br />
<br />
== Caveats ==<br />
{{Out of date|As of the [https://www.archlinux.org/news/install-media-20120715-released/ 2012.07.15 installation media release], AIF (the Arch Installation Framework) is no longer included but instead [https://github.com/falconindy/arch-install-scripts Arch Install Scripts] are provided to aid in the installation process. Some of the content still has to get updated on this page. Currently (May 2013) this is Section 8 (Encrypted LVM) in particular and 4.5 (AIF legacy instructions). <br />
Keep in mind while reading that out-of-date content is marked per section (or even per paragraph in some few cases). Hence, it does not imply the next section (or paragraph) is out-of-date either!}}<br />
<br />
== Initial Setup ==<br />
=== Overview and Preparation ===<br />
The installation of a LUKS-encrypted system is largely the same as installing an unencrypted system. Routine creation of an encrypted system follows these general steps:<br />
<br />
::* Secure erasure of the hard disk drive(s)<br />
::* Partitioning and setup of encryption ([[LVM]] optional)<br />
::* Routine package selection and installation<br />
::* System Configuration<br />
<br />
This page covers the first two points in a general way for different configuration options available with LUKS. <br />
<br />
The third and fourth point are covered in the later sections. Since the Arch installation media comes with all the tools required for system encryption, you can follow the [[Installation Guide]] or the [[Beginners' Guide]] after the encrypted partitions are set up. You will have to adjust the system configuration to be able to boot from your LUKS-volumes though. <br />
<br />
{{Warning | Encrypting a partition will erase everything currently on that partition. Please make appropriate data backups prior to starting.}}<br />
<br />
=== Secure erasure of the hard disk drive ===<br />
{{Note|The following methods are specifically to dm-crypt/LUKS. For detailed instructions on how to erase and prepare a drive consult: [[Securely wipe disk]]}}<br />
<br />
Before encrypting a drive, you should perform a secure erase of the disk by overwriting the entire drive with random data. To prevent cryptographic attacks or unwanted [[File Recovery]], this data should be completely indistinguishable from all data later written by dm-crypt.<br />
<br />
In deciding which method to use for secure erasure of a hard disk drive, remember that this will not need to be performed more than once for as long as the drive is used as an encrypted drive.<br />
<br />
==== Use LUKS container as pseudorandom number generator (alternate) ====<br />
<br />
The [http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions#5._Security_Aspects cryptsetup FAQ] mentions a very simple procedure to use an existing dm-crypt-volume to wipe all free space accessible on the underlying block device with random data by acting as a simple pseudorandom number generator. It is also claimed to protect against disclosure of usage patterns.<br />
<br />
{{bc|1=<br />
# dd if=/dev/zero of=/dev/mapper/luks-container}}<br />
<br />
===== Wipe free space with encrypted file after Installation =====<br />
<br />
The same effect can be achieved if a file is created on each encrypted partition that fills the partition completely after the system is installed, booted and filesystems mounted. That is because encrypted data is indistinguishable from random.<br />
<br />
{{bc|1=<br />
# dd if=/dev/zero of=/file/in/luks-container<br />
# rm /file/in/luks-container}}<br />
<br />
Obviously the above process has to be repeated for every container created.<br />
<br />
==== Wipe LUKS keyslots ====<br />
#cryptsetup luksKillSlot <device> <key slot number><br />
<br />
This will only wipe a single keyslot.<br />
<br />
==== Wipe LUKS header ====<br />
The partitions formatted with dm-crypt/LUKS contain a header with the cipher and crypt-options used, which is referred to {{ic|dm-mod}} when opening the blockdevice. After the header the actual random data partition starts. Hence, when de-commissioning a drive (e.g. sale of PC, switch of drives, etc.) it ''may'' be just enough to wipe the header of the partition, rather than overwriting the whole drive - which can be a lengthy process. <br />
<br />
Wiping the LUKS header will delete the PBKDF2-encrypted (AES) master key, salts and so on.<br />
<br />
{{Note|It is crucial to write to the LUKS encrypted partition ({{ic|/dev/sda'''1'''}} in this example) and not directly to the disks device node. If you did set up encryption as a device-mapper layer on top of others, e.g. LVM on LUKS on RAID then write to RAID respectively.}}<br />
<br />
A header with one single default 256 bit size keyslot is 1024KB in size. It is advised to also overwrite the first 4KB written by dm-crypt, so 1028KB have to be wiped. That is {{ic|1052672}} Byte.<br />
<br />
For zero offset use:<br />
#head -c 1052672 /dev/zero > /dev/sda1; sync<br />
<br />
For 512 bit key length (e.g. for aes-xts-plain with 512 bit key) the header is 2MB.<br />
<br />
If in doubt, just be generous and overwrite the first 10MB or so.<br />
<br />
#dd if=/dev/zero of=/dev/sda1 bs=512 count=20480<br />
<br />
{{Note|With a backup-copy of the header data can get rescued but the filesystem was likely damaged as the first encrypted sectors were overwritten. See further sections on how to make a backup of the crucial header blocks.}}<br />
<br />
When wiping the header with random data and the header is followed by encrypted data written ontop random data everything left is random data.<br />
<br />
====Discard/TRIM support for solid state disks (SSD)====<br />
Solid state disk users should be aware that by default, Linux's full-disk encryption mechanisms will ''not'' forward TRIM commands from the filesystem to the underlying disk. The device-mapper maintainers have made it clear that TRIM support will never be enabled by default on dm-crypt devices because of the potential security implications.<br />
<br />
Most users will still want to use TRIM on their encrypted SSDs. Minimal data leakage in the form of freed block information, perhaps sufficient to determine the filesystem in use, may occur on devices with TRIM enabled. An illustration and discussion of the issues arising from activating TRIM is available in the [http://asalor.blogspot.de/2011/08/trim-dm-crypt-problems.html blog] of a {{ic|cryptsetup}} developer.<br />
<br />
As a semi-tangential caveat, it is worth noting that because TRIM provides information to the disk firmware about which blocks contain data, encryption schemes that rely on plausible deniability, like TrueCrypt's hidden volumes, should never be used on a device that utilizes TRIM. This is probably also valid for TC containers within a LUKS encrypted device that uses TRIM.<br />
<br />
TrueCrypt's developers also recommend against using any TC volume on a device that performs wear-leveling techniques to extend the life of the disk; most flash devices, including SSDs and USB flash drives, use mandatory wear-leveling at the firmware level. LUKS devices are probably not vulnerable to problems with wear-leveling if the entire device is blanked before the LUKS partition is initialized. See http://www.truecrypt.org/docs/?s=trim-operation and http://www.truecrypt.org/docs/?s=wear-leveling for more information.<br />
<br />
In {{Pkg|linux}} 3.1 and up, support for dm-crypt TRIM pass-through can be toggled upon device creation or mount with dmsetup. Support for this option also exists in {{Pkg|cryptsetup}} version 1.4.0 and up. To add support during boot, you will need to add {{ic|:allow-discards}} to the {{ic|cryptdevice}} option. The TRIM option may look like this:<br />
cryptdevice=/dev/mapper/root:root:allow-discards<br />
<br />
For the main {{ic|cryptdevice}} configuration options before the {{ic|:allow-discards}} please refer to the sections following. Besides the kernel option, it is also required to mount the filesystem (e.g. {{ic|/dev/mapper/root}} in this example) with the {{ic|discard}} option in {{ic|/etc/fstab}}. For details, please refer to the [[SSD#TRIM|SSD]] page.<br />
<br />
===Partitioning===<br />
<br />
After the drive has been securely overwritten, it is time to create partitions and begin setting up an encrypted system.<br />
<br />
There are multiple ways to create disk partitions:<br />
<br />
::*Standard partitions<br />
::*[[#LVM:_Logical_Volume_Manager|LVM]]<br />
::*[[RAID]]<br />
<br />
LUKS is compatible with systems that require LVM and/or RAID as well as with with standard primary, extended, and logical partitions.<br />
<br />
====Standard Partitions====<br />
<br />
These are the partitions that most people are familiar with. They come in three flavors: primary partitions, extended partitions, and logical partitions.<br />
<br />
;Primary Partitions: These are the normal partitions recognized by the system BIOS. There can be up to four of these stored in the MBR.<br />
<br />
;Extended Partitions: These are primary partitions that also define another partition within themselves. Extended partitions were created to work around the original limit of four primary partitions.<br />
<br />
;Logical Partitions: These are the partitions that are defined within extended partitions.<br />
<br />
====LVM: Logical Volume Manager====<br />
<br />
The LVM allows for creation of volume groups for systems that require complex combinations of multiple hard disk drives and partitions that are not possible with standard partitions. LVM is covered in detail in the [[LVM|Article on LVM]] which is recommended reading prior to continuing with the instructions on [[Dm-crypt_with_LUKS#Encrypting_a_LVM_setup|setting up LUKS with LVM]] located below.<br />
<br />
{{Tip|Btrfs has a built-in [[Btrfs#Subvolumes|Subvolume-Feature]] that fully replaces the need for LVM if no other filesystems are required. An encrypted swap is not possible this way and swap files are [https://btrfs.wiki.kernel.org/index.php/FAQ#Does_btrfs_support_swap_files.3F not supported] by btrfs up to now.}}<br />
<br />
{{Poor writing|Due to uncomprehensible disarrangement this small section on stacking of device-mapper layers was overcomplicated to read. Now different setups are seperated by subsection-headings, nevertheless language and content still need improvement and duplicates should get deleted.}}<br />
<br />
=====LVM on LUKS=====<br />
<br />
There is a growing preference towards logical volume management of LUKS encrypted physical media (LVM on LUKS). The deployment of LVM on LUKS is considered much more generalizable. In a LVM on LUKS scenario, the LUKS-partition has to be opened and mapped before LVM can access the underlaying setup volumes.<br />
<br />
One reason for this is that using LUKS as the lowest level of infrastructure most closely approximates the deployment of physical disks with built-in hardware encryption. In that case, logical volume management would be layered on top of the hardware encryption - usage of LUKS would be superfluous.<br />
<br />
=====LUKS on LVM=====<br />
<br />
It is possible there may exist usage scenarios where encrypting logical volumes rather than physical disks is required (LUKS on LVM).<br />
A usage scenario for LUKS on LVM exists where utmost flexibility for assigning available diskspace or a mix of unencrypted and encrypted volumes is desired. Upon boot the LVM is setup and assigned before the LUKS-encrypted volumes are opened. In order to manage changes of volumes in a LUKS on LVM setup, both module layers' setup have to be taken into account, i.e. shrinking or expanding an encrypted volume has to include the resizing of the encrypted LUKS blockdevice to ensure integrity of it and the filesystem. That said, in simpler scenarios the usage of LVM may be superfluous.<br />
<br />
====Creating Disk Partitions====<br />
<br />
Disk partitions are created using:<br />
<br />
# cfdisk<br />
<br />
This will display a graphical interface for creating disk partitions.<br />
<br />
There are two required partitions for any encrypted system:<br />
<br />
; root file system: {{ic|'''/'''}} Will be encrypted and store all system and user files ({{ic|/usr}}, {{ic|/bin}}, {{ic|/var}}, {{ic|/home}}, etc.)<br />
<br />
; initial boot partition: {{ic|'''/boot'''}} Will ''not'' be encrypted; the bootloader needs to access the {{ic|/boot}} directory where it will load the initramfs/encryption modules needed to load the rest of the system which ''is'' encrypted (see [[Mkinitcpio]] for details). For this reason, {{ic|/boot}} needs to reside on its own, unencrypted partition.<br />
{{Out of date|It is now possible to include /boot on a LUKS container thanks to grub 2.00. Zack Buhman (buhman) has proposed a patch which allows this. [https://bugs.archlinux.org/task/31877]}}<br />
<br />
{{Note| A swap partition is optional; it can be encrypted with dm-crypt/LUKS. See [[#Encrypting_the_Swap_partition|Encrypting the Swap Partition]] for details.}}<br />
<br />
=====Single Disk Systems=====<br />
<br />
Depending on the system demands, there may be additional partitions desired. These partitions can be individually created at this level by defining separate primary or extended/logical partitions. However, if LVM is to be used, the space unoccupied by {{ic|/boot}} and swap should be defined as single large partition which will be divided up later at the LVM level.<br />
<br />
=====Multiple Disk Systems=====<br />
<br />
In systems that will have multiple hard disk drives, the same options exist as a single disk system. After the creation of the {{ic|/boot}} and swap partitions, the remaining free space on physical disks can divided up into their respective partitions at this level, or large partitions can define all free space per physical disk with intent to partition them within the LVM.<br />
<br />
== Configuring LUKS ==<br />
This section covers how to manually utilize LUKS from the command line to encrypt a system. <br />
<br />
=== Mapping Physical Partitions to LUKS ===<br />
After writing the partition table to the MBR (optionally set up LVM thereafter) the next step is to create the LUKS and dm-crypt magic and make device mapper mount it to the filesystem of the installation system.<br />
<br />
When creating LUKS partitions they must be associated with a key. The key is used to unlock the header of the LUKS-encrypted partitions.<br />
<br />
A key is either a: <br />
<br />
*Passphrase<br />
*Keyfile <br />
<br />
It is possible to define up to 8 different keys per LUKS partition. This enables the user to create access keys for save backup storage. Also a different key-slot could be used to grant access to a partition to a user by issuing a second key and later revoking it again without the need to re-encrypt the partition. Having in mind that further passphrases or keyfiles can be added later easily at any time might make the choice for the initial key easier. <br />
<br />
==== Using LUKS to Format Partitions with a Passphrase ====<br />
{{Note|Using a passphrase to decrypt LUKS partitions automatically from {{ic|/etc/crypttab}} is [http://www.mail-archive.com/arch-projects@archlinux.org/msg02115.html deprecated.]}}<br />
<br />
Cryptsetup is used to interface with LUKS for formatting, mounting and unmounting encrypted partitions.<br />
<br />
Usage:<br />
# cryptsetup [OPTION...] <action> <action-specific><br />
<br />
Example:<br />
# cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random --verify-passphrase luksFormat <device> <br />
<br />
Common options used with luksFormat:<br />
<br />
{| class="wikitable" style="margin:0 5em 0.5em 0.5em 0.5em;"<br />
! scope="col" style="text-align:left" | Available&nbsp;options<br />
! scope="col" style="text-align:left" | Cryptsetup (<1.6.0) defaults <br />
! scope="col" style="text-align:left" | Comment<br />
! scope="col" style="text-align:left" | Example<br />
! scope="col" style="text-align:left" | Comment<br />
|-<br />
! scope="row" style="text-align:right" | --cipher, -c<br />
| {{ic|aes-cbc-essiv:sha256}}<br />
| Use the AES-[[Disk_Encryption#Ciphers_and_modes_of_operation|cipher]] with [http://en.wikipedia.org/wiki/Disk_encryption_theory#Cipher-block_chaining_.28CBC.29 CBC/ESSIV].<br />
| {{ic|aes-xts-plain64}}<br />
| [http://en.wikipedia.org/wiki/Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29 XTS]. For volumes >2TiB use {{ic|aes-xts-plain64}} (requires kernel >= 2.6.33).<br />
|-<br />
! scope="row" style="text-align:right" | --key-size, -s<br />
| {{ic|256}}<br />
| The cipher is used with 256 bit key-size.<br />
| {{ic|512}}<br />
| [http://en.wikipedia.org/wiki/XEX-TCB-CTS#Issues_with_XTS XTS splits the supplied key] into fraternal twins. For an effective AES-256 the XTS key-size must be {{ic|512}}.<br />
|-<br />
! scope="row" style="text-align:right" | --hash, -h<br />
| {{ic|sha1}}<br />
| Hash algorithm used for [[Disk_Encryption#Keys.2C_keyfiles_and_passphrases|PBKDF2]].<br />
| {{ic|sha512}}<br />
| <br />
|-<br />
! scope="row" style="text-align:right" | --iter-time, -i<br />
| {{ic|1000}}<br />
| Number of milliseconds to spend with PBKDF2 passphrase processing.<br />
| {{ic|5000}}<br />
| Using a hash stronger than sha1 results in less iterations if iter-time is not increased.<br />
|-<br />
! scope="row" style="text-align:right" | --use-random<br />
| {{ic|--use-'''u'''random}}<br />
| /dev/u[[Random|random]] is used as randomness source for the (long-term) volume master key.<br />
| {{ic|--use-random}}<br />
| Avoid generating an insecure master key if low on entropy. Will block if the entropy pool is used up.<br />
|-<br />
! scope="row" style="text-align:right" | --verify-passphrase, -y<br />
| Yes<br />
| Default only for luksFormat and luksAddKey.<br />
| -<br />
| No need to type for archlinux at the moment.<br />
|}<br />
<br />
Please note that the above compares historic cryptsetup defaults in the left column. With release 1.6.0 the defaults have changed to an AES cipher in XTS mode, but with other options than the right column example (e.g. an effective key-size of 128-bit). The defaults can be checked with the tail output of <br />
# cryptsetup --help<br />
When deciding on the encryption cipher to use during blockdevice creation, it has to be taken into account that a number of the options stated affect system performance just for creating the initial crypt-blockdevice or opening it, but not the crypto and disk-io operations when the system is running. The throughput and security of the crypted data itself depends on the cipher and key-size. The used hash, iteration-time and random source options affect the cryptographic security of the master-key creation and processing time needed to unlock it in the future. <br />
<br />
A full list of options {{ic|cryptsetup}} accepts can be found in the [http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=cryptsetup manpage]. Furthermore, {{ic|cryptsetup}} now has a feature to benchmark the crypto performance of the processor:<br />
# cryptsetup benchmark <br />
can give guidance on deciding for a cipher to use prior to installation. <br />
<br />
In the following examples for creating LUKS partitions, we will use the AES cipher in XTS mode; at present this is not only the default, but also a most generally used preferred cipher.<br />
More information this and other ciphers used with cryptsetup can be found here: [[Wikipedia:Block_cipher]]<br />
<br />
'''Formatting LUKS Partitions'''<br />
<br />
First of all make sure the device mapper kernel module is loaded by executing the following: {{ic|# modprobe dm_mod}}<br />
<br />
In order to format a desired partition as an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup -c <cipher> -y -s <key size> luksFormat /dev/<partition name>|<br />
Enter passphrase: <password><br />
Verify passphrase: <password>}}<br />
<br />
Check results:<br />
# cryptsetup luksDump /dev/<drive><br />
<br />
This should be repeated for all partitions except for {{ic|/boot}} and possibly swap. You will note that the dump not only shows the cipher header information, but also the key-slots in use for the LUKS partition. <br />
<br />
The example below will create an encrypted root partition using the AES cipher in XTS mode (generally referred to as ''XTS-AES'').<br />
{{bc|# cryptsetup -c aes-xts-plain -y -s 512 luksFormat /dev/sda2}}<br />
<br />
{{Note|If hibernation usage is planned, swap must be encrypted in this fashion; otherwise, if hibernation is not a planned feature for the system, encrypting the swap file will be performed in a alternative manner.}}<br />
<br />
{{Warning|Irrespective of the chosen partitioning method, the {{ic|/boot}} partition must remain separate and unencrypted in order to load the kernel and boot the system.}}<br />
<br />
'''Unlocking/Mapping LUKS Partitions with the Device Mapper'''<br />
<br />
Once the LUKS partitions have been created it is time to unlock them.<br />
<br />
The unlocking process will map the partitions to a new device name using the device mapper. This alerts the kernel that {{ic|/dev/<partition name>}} is actually an encrypted device and should be addressed through LUKS using the {{ic|/dev/mapper/<name>}} so as not to overwrite the encrypted data. To guard against accidental overwriting, read about the possibilities to [[LUKS#Backup_the_cryptheader|backup the cryptheader]] after finishing setup.<br />
<br />
In order to open an encrypted LUKS partition execute:<br />
{{hc|# cryptsetup luksOpen /dev/<partition name> <device-mapper name>|<br />
Enter any LUKS passphrase: <password><br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
Usually the device mapped name is descriptive of the function of the partition that is mapped, example:<br />
<br />
; cryptsetup luksOpen /dev/sda2 swap: Once opened, the swap partition device address would be {{ic|/dev/mapper/swap}} instead of {{ic|/dev/sda2}}.<br />
<br />
; cryptsetup luksOpen /dev/sda3 root: Once opened, the root partition device address would be {{ic|/dev/mapper/root}} instead of {{ic|/dev/sda3}}.<br />
<br />
; cryptsetup luksOpen /dev/sda3 lvmpool (alternate): For setting up [[#LVM:_Logical_Volume_Manager|LVM]] ontop the encryption layer the device file for the decrypted volume group would be anything like {{ic|/dev/mapper/lvmpool}} instead of {{ic|/dev/sda3}}. LVM will then give additional names to all logical volumes created, e.g. {{ic|/dev/mapper/lvmpool-root}} and {{ic|/dev/mapper/lvmpool-swap}}.<br />
<br />
In order to write encrypted data into the partition it must be accessed through the device mapped name.<br />
<br />
{{Note|Since {{ic|/boot}} is not encrypted, it does not need a device mapped name and will be addressed as {{ic|/dev/sda1}}.}}<br />
<br />
==== Using LUKS to Format Partitions with a Keyfile ====<br />
{{Note|This section describes using a plaintext keyfile. If you want to encrypt your keyfile giving you two factor authentication see [https://wiki.archlinux.org/index.php/System_Encryption_with_LUKS#Using_GPG_or_OpenSSL_Encrypted_Keyfiles Section 9] for details, but please still read this section.}}<br />
<br />
'''What is a Keyfile?'''<br />
<br />
A keyfile is any file in which the data contained within it is used as the passphrase to unlock an encrypted volume.<br />
Therefore if these files are lost or changed, decrypting the volume will no longer be possible.<br />
<br />
{{Tip|Define a passphrase in addition to the keyfile for backup access to encrypted volumes in the event the defined keyfile is lost or changed.}}<br />
<br />
'''Why use a Keyfile?'''<br />
<br />
There are many kinds of keyfile. Each type of keyfile used has benefits and disadvantages summarized below:<br />
<br />
:'''keyfile.passphrase:'''<br />
::this is my passphrase I would have typed during boot but I have placed it in a file instead<br />
<br />
This is a keyfile containing a simple passphrase. The benefit of this type of keyfile is that if the file is lost the data it contained is known and hopefully easily remembered by the owner of the encrypted volume. However the disadvantage is that this does not add any security over entering a passphrase during the initial system start.<br />
<br />
:'''keyfile.randomtext:'''<br />
::fjqweifj830149-57 819y4my1- 38t1934yt8-91m 34co3;t8y;9p3y-<br />
<br />
This is a keyfile containing a block of random characters. The benefit of this type of keyfile is that it is much more resistant to dictionary attacks than a simple passphrase. An additional strength of keyfiles can be utilized in this situation which is the length of data used. Since this is not a string meant to be memorized by a person for entry, it is trivial to create files containing thousands of random characters as the key. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase.<br />
<br />
:'''keyfile.binary:'''<br />
::where any binary file, images, text, video could be chosen as the keyfile<br />
<br />
This is a binary file that has been defined as a keyfile. When identifying files as candidates for a keyfile, it is recommended to choose files that are relatively static such as photos, music, video clips. The benefit of these files is that they serve a dual function which can make them harder to identify as keyfiles. Instead of having a text file with a large amount of random text, the keyfile would look like a regular image file or music clip to the casual observer. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase. Additionally, there is a theoretical loss of randomness when compared to a randomly generated text file. This is due to the fact that images, videos and music have some intrinsic relationship between neighboring bits of data that does not exist for a text file. However this is controversial and has never been exploited publicly.<br />
<br />
'''Creating a Keyfile with Random Characters'''<br />
<br />
Here {{ic|dd}} is used to generate a keyfile of 2048 random bytes.<br />
<br />
# dd if=/dev/urandom of=mykeyfile bs=512 count=4<br />
<br />
The usage of {{ic|dd}} is similar to initially wiping the volume with random data prior to encryption. <br />
<br />
{{Warning|Do not use [[badblocks]] here. It only generate a random pattern which just repeats its randomness over and over again.}}<br />
<br />
'''Creating a new LUKS encrypted partition with a Keyfile'''<br />
<br />
When creating a new LUKS encrypted partition, a keyfile may be associated with the partition on its creation using:<br />
<br />
# cryptsetup -c <desired cipher> -s <key size> luksFormat /dev/<volume to encrypt> '''/path/to/mykeyfile'''<br />
<br />
This is accomplished by appending the bold area to the standard cryptsetup command which defines where the keyfile is located.<br />
<br />
==== Adding Additional Passphrases or Keyfiles to a LUKS Encrypted Partition ====<br />
<br />
LUKS supports the association of up to 8 keyslots with any single encrypted volume.<br />
Keyslots can be either keyfiles or passphrases.<br />
<br />
Once an encrypted partition has been created, the initial keyslot 0 is created. Additional keyslots are numbered from 1 to 7.<br />
<br />
Adding new keyslots is accomplished using cryptsetup with the {{ic|luksAddKey}} action.<br />
<br />
Don't forget wiping unused keyslots with {{ic|luksKillSlot}} as described in [[#Wipe LUKS keyslots]].)<br />
<br />
{{hc|# cryptsetup luksAddKey /dev/<volume> (/path/to/<additionalkeyfile>)|<br />
Enter any passphrase:<br />
Enter new passphrase for key slot:<br />
Verify passphrase:}}<br />
<br />
Where <device> is the volume containing the LUKS header to wich the new keyslot is added. This works on header backup files as well.<br />
<br />
If {{ic|/path/to/<additionalkeyfile>}} is given, cryptsetup will add a new keyslot for <additionalkeyfile>. Otherwise a new passphrase will be prompted for twice.<br />
<br />
For adding keyslots cryptsetup has to decrypt the master key from an existing keyslot so it first asks for "any passphrase" (of an existing keyslot).<br />
<br />
For getting the master key from an existing keyfile keyslot the {{ic|--key-file}} or {{ic|-d}} option followed by the "old" <keyfile> will try to unlock all available keyfile keyslots.<br />
<br />
# cryptsetup luksAddKey /dev/mapper/<device> (/path/to/<additionalkeyfile>) -d /path/to/<keyfile><br />
<br />
=== Storing the Key File ===<br />
<br />
==== External Storage on a USB Drive ====<br />
<br />
=====Preparation for Persistent block device naming=====<br />
<br />
For reading the file from an external storage device it is very convenient to access it through udev's [[Persistent block device naming]] features and not by ordinary device nodes like {{ic|/dev/sdb1}} whose naming depends on the order in which devices are plugged in. So in order to assure that the {{ic|encrypt}} HOOK in the initcpio finds your keyfile, you must use a permanent device name. <br />
<br />
=====Persistent symlinks=====<br />
<br />
{{Merge|Persistent block device naming|Anything not specific to storing LUKS keyfiles should get merged there.}}<br />
<br />
A quick method (as opposed to setting up a [[udev]] rule) for doing so involves referencing the right partition by its UUID, id (based on hardware info and serial number) or filesystem label.<br />
<br />
Plug the device in and print every file name under /dev/disk:<br />
<br />
{{hc|#ls -lR /dev/disk/|<br />
/dev/disk/:<br />
total 0<br />
drwxr-xr-x 2 root root 180 Feb 12 10:11 by-id<br />
drwxr-xr-x 2 root root 60 Feb 12 10:11 by-label<br />
drwxr-xr-x 2 root root 100 Feb 12 10:11 by-path<br />
drwxr-xr-x 2 root root 180 Feb 12 10:11 by-uuid<br />
<br />
/dev/disk/by-id:<br />
total 0<br />
lrwxrwxrwx 1 root root 9 Feb 12 10:11 usb-Generic_STORAGE_DEVICE_000000014583-0:0 -> ../../sdb<br />
lrwxrwxrwx 1 root root 10 Feb 12 10:11 usb-Generic_STORAGE_DEVICE_000000014583-0:0-part1 -> ../../sdb1<br />
<br />
/dev/disk/by-label:<br />
total 0<br />
lrwxrwxrwx 1 root root 10 Feb 12 10:11 Keys -> ../../sdb1<br />
<br />
/dev/disk/by-path:<br />
total 0<br />
lrwxrwxrwx 1 root root 9 Feb 12 10:11 pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 -> ../../sdb<br />
lrwxrwxrwx 1 root root 10 Feb 12 10:11 pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 -> ../../sdb1<br />
<br />
/dev/disk/by-uuid:<br />
total 0<br />
lrwxrwxrwx 1 root root 10 Feb 12 10:11 baa07781-2a10-43a7-b876-c1715aba9d54 -> ../../sdb1}}<br />
<br />
'''UUID'''<br />
<br />
Using the filesystem UUID for persistent block device naming is considered very reliable. Filesystem UUIDs are stored in the filesystem itself, meaning that the UUID will be the same if you plug it into any other computer, and that a dd backup of it will always have the same UUID since dd does a bitwise copy.<br />
<br />
The right device node for what is now {{ic|/dev/sdb1}} will always get symlinked by {{ic|/dev/disk/by-uuid/baa07781-2a10-43a7-b876-c1715aba9d54}}. Symlinks can be used in the bootloaders "cryptkey" kernel option or anywhere else.<br />
<br />
For legacy filesystems like FAT the UUID will be much shorter but collision is still unlikely to happen if not mounting many different FAT filesystems at once.<br />
<br />
'''Label'''<br />
<br />
In the following example a FAT partition is labeled as "Keys" and will always get symlinked by {{ic|/dev/disk/by-label/Keys}}:<br />
<br />
#mkdosfs -n >volume-name< /dev/sdb1<br />
<br />
{{hc|#blkid -o list|<br />
device fs_type label mount point UUID<br />
<nowiki>-------------------------------------------------------</nowiki><br />
/dev/sdb1 vfat Keys (not mounted) 221E-09C0}}<br />
<br />
{{Note|If you plan to store the keyfile between [[#Storing_the_key_between_MBR_and_1st_partition|MBR and the 1st partition]] you '''cannot use this method''', since it only allows access to the partitions ({{ic|sdb1}}, {{ic|sdb2}}, ...) but not to the USB device ({{ic|sdb}}) itself. Use something like {{ic|/dev/disk/by-id/*}} or alternatively create a udev rule as described in the following section.}}<br />
<br />
=====Persistent udev rule=====<br />
Optionally you may choose to set up your flash drive with a [[udev]] rule. There is some documentation in the Arch wiki about that already; if you want more in-depth, structural info, read [http://reactivated.net/writing_udev_rules.html this guide]. Here is quickly how it goes.<br />
<br />
Get the serial number from your USB flash drive:<br />
lsusb -v | grep -A 5 Vendor<br />
<br />
Create a udev rule for it by adding the following to a file in {{ic|/etc/udev/rules.d/}}, such as {{ic|8-usbstick.rules}}:<br />
KERNEL=="sd*", ATTRS{serial}=="$SERIAL", SYMLINK+="$SYMLINK%n"<br />
<br />
Replace {{ic|$SYMLINK}} and {{ic|$SERIAL}} with their respective values. {{ic|%n}} will expand to the partition (just like sda is subdivided into sda1, sda2, ...). You do not need to go with the 'serial' attribute. If you have a custom rule of your own, you can put it in as well (e.g. using the vendor name).<br />
<br />
Rescan your sysfs:<br />
udevadm trigger<br />
Now check the contents of {{ic|/dev}}:<br />
ls /dev<br />
It should show your device with your desired name.<br />
<br />
==== Generating the keyfile ====<br />
Optionally you can mount a tmpfs for storing the temporary keyfile.<br />
# mkdir ./mytmpfs<br />
# mount tmpfs ./mytmpfs -t tmpfs -o size=32m<br />
# cd ./mytmpfs<br />
The advantage is that it resides in RAM and not on a physical disk, so after unmounting your keyfile is securly gone.<br />
So copy your keyfile to some place you consider as secure before unmounting.<br />
If you are planning to store the keyfile as a plain file on your USB device, you can also simply execute the following command in the corresponding directory, e.g. {{ic|/media/sdb1}}<br />
<br />
The keyfile can be of arbitrary content and size. We will generate a random temporary keyfile of 2048 bytes:<br />
# dd if=/dev/urandom of=secretkey bs=512 count=4<br />
<br />
If you stored your temporary keyfile on a physical storage device, remember to not just (re)move the keyfile later on, but use something like<br />
cp secretkey /destination/path<br />
shred --remove --zero secretkey<br />
to securely overwrite it. For overaged filesystems like FAT or ext2 this will suffice while in the case of journaling filesystems, flash memory hardware and other cases it is highly recommended to [[Securely wipe disk|wipe the entire device]] or at least the keyfiles partition.<br />
<br />
Add a keyslot for the temporary keyfile to the LUKS header:<br />
{{hc|# cryptsetup luksAddKey /dev/sda2 secretkey|<br />
Enter any LUKS passphrase:<br />
key slot 0 unlocked.<br />
Command successful.}}<br />
<br />
==== Storing the keyfile ====<br />
To store the key file, you have two options. The first is less risky than the other, but perhaps a bit more secure (if you consider security by obscurity as more secure).<br />
In any case you have to do some further configuration, if not already done above.<br />
<br />
==== Configuration of initcpio ====<br />
You have to add two extra modules in your {{ic|/etc/mkinitcpio.conf}}, one for the drive's file system and one for the codepage. Further if you created a udev rule, you should tell {{ic|mkinitcpio}} about it:<br />
MODULES="ata_generic ata_piix nls_cp437 vfat"<br />
FILES="/etc/udev/rules.d/8-usbstick.rules"<br />
In this example it is assumed that you use a FAT formatted USB drive. Replace those module names if you use another file system on your USB stick (e.g. ext2) or another codepage. Users running the stock Arch kernel should stick to the codepage mentioned here.<br />
<br />
If you have a non-US keyboard, it might prove useful to load your keyboard layout before you are prompted to enter the password to unlock the root partition at boot. For this, you will need the {{ic|keymap}} hook before {{ic|encrypt}}.<br />
<br />
Generate a new image (maybe you should backup a copy of your old {{ic|/boot/initramfs-linux.img}} first):<br />
# mkinitcpio -p linux<br />
<br />
==== Storing the key as a plain (visible) file ====<br />
Be sure to choose a plain name for your key &ndash; a bit of 'security through obscurity' is always nice ;-). Avoid using dotfiles (hidden files) &ndash; the {{ic|encrypt}} hook will fail to find the keyfile during the boot process.<br />
<br />
You have to add {{ic|1=cryptdevice=/dev/sda3:root cryptkey=/dev/usbstick:vfat:/secretkey}} to your [[kernel parameters]]. This assumes {{ic|/dev/usbstick}} is the FAT partition of your choice. Replace it with {{ic|/dev/disk/by-...}} or whatever your device is.<br />
<br />
That is all, reboot and have fun!<br />
<br />
==== Storing the key between MBR and 1st partition ====<br />
We will write the key directly between the Master Boot Record (MBR) and the first partition.<br />
<br />
{{Warning|You should only follow this step if you know what you are doing -- '''it can cause data loss and damage your partitions or MBR on the stick!'''}}<br />
<br />
{{Out of date|[[GRUB Legacy]] is not available anymore and for [[GRUB]] a 1-2MB gap between MBR and the beginning of other written data (e.g. first partition or LUKS-key) is needed for embedding GRUB's {{ic|core.img}}. Information regarding GPT and/or UEFI combinations are required. GRUB has changed parsing configuration.}}<br />
<br />
If you have a bootloader installed on your drive you have to adjust the values. E.g. [[GRUB]] needs the first 16 sectors (actually, it depends on the type of the file system, so do not rely on this too much), so you would have to replace {{ic|seek<nowiki>=</nowiki>4}} with {{ic|seek<nowiki>=</nowiki>16}}; otherwise you would overwrite parts of your GRUB installation. When in doubt, take a look at the first 64 sectors of your drive and decide on your own where to place your key. <br />
<br />
''Optional''<br />
If you do not know if you have enough free space before the first partition, you can do<br />
dd if=/dev/usbstick of=64sectors bs=512 count=64 # gives you copy of your first 64 sectors<br />
hexcurse 64sectors # determine free space<br />
xxd 64sectors | less # alternative hex viewer<br />
<br />
Write your key to the disk:<br />
dd if=secretkey of=/dev/usbstick bs=512 seek=4<br />
<br />
If everything went fine you can now overwrite and delete your temporary secretkey as noted above.<br />
You should not simply use {{ic|rm}} as the keyfile would only be unlinked from your filesystem and be left physically intact.<br />
<br />
Now you have to add a kernel parameter in your {{ic|/boot/grub/menu.lst}} file (GRUB); it should look something like this:<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda3:root root=/dev/mapper/root ro cryptkey=/dev/usb:2048:2048<br />
Format for the {{ic|cryptkey}} option:<br />
cryptkey=BLOCKDEVICE:OFFSET:SIZE<br />
{{ic|OFFSET}} and {{ic|SIZE}} match in this example, but this is just coincidence - they can differ (and often will). An other possible example could be<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda3:root root=/dev/mapper/root ro cryptkey=/dev/usb:8192:2048<br />
That is all, reboot and have fun! And look if your partitions still work after that ;-).<br />
<br />
=== Encrypting the Swap partition ===<br />
<br />
==== Without suspend-to-disk support ====<br />
<br />
In systems where suspend to disk is not a desired feature, it is possible to create a swap file that will have a random master key with each boot. This is accomplished by using dm-crypt directly without LUKS extensions.<br />
<br />
The {{ic|/etc/crypttab}} is well commented and you can basically just uncomment the swap line and change <device> to a persistent symlink.<br />
<br />
{{hc|/etc/crypttab|# <name> <device> <password> <options><br />
# swap /dev/hdx4 /dev/urandom <nowiki>swap,cipher=aes-cbc-essiv:sha256,size=256</nowiki>}}<br />
<br />
Where:<br />
; <name>: Represents the name ({{ic|/dev/mapper/<name>}}) to list in /etc/fstab.<br />
; <device>: Should be the symlink to the actual partition's device file.<br />
; <password>: {{ic|/dev/urandom}} sets the dm-crypt master key to be randomized on every volume recreation.<br />
; <options>: The {{ic|swap}} option runs mkswap after cryptographic's are setup.<br />
<br />
{{Warning|You should use persistent block device naming (in example ID's) for <device> because if there are multiple hard drives installed in the system, their naming order (sda, sdb,...) can occasionally be scrambled upon boot and thus the swap would be created over a valuable file system, destroying its content.}}<br />
<br />
Persistent block device naming is implemented with simple symlinks. Using UUID's or filesystem-labels is not possible as plain dm-crypt writes only encrypted data without a persistent header like LUKS. If you are not familar with one of the directories under {{ic|/dev/disk/}} read on in the section on [[#Preparation for Persistent block device naming]]<br />
<br />
{{hc|#ls -l <nowiki>/dev/disk/*/* |</nowiki> grep sda2|<br />
lrwxrwxrwx 1 root root 10 Oct 12 16:54 /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part2 -> ../../sda2}}<br />
<br />
Example line for the {{ic|/dev/sda2}} symlink from above:<br />
<br />
{{hc|/etc/crypttab|# <name> <device> <password> <options><br />
swap /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part2 /dev/urandom <nowiki>swap,cipher=aes-cbc-essiv:sha256,size=256</nowiki>}}<br />
<br />
This will map {{ic|/dev/sda2}} to {{ic|/dev/mapper/swap}} as a swap partition that can be added in {{ic|/etc/fstab}} like a normal swap.<br />
<br />
If the partition chosen for swap was previously a LUKS partition, crypttab will not overwrite the partition to create a swap partition. This is a safety measure to prevent data loss from accidental mis-identification of the swap partition in crypttab. In order to use such a partition the [[#Wipe_LUKS_header|LUKS header must be overwritten]] once.<br />
<br />
==== With suspend-to-disk support ====<br />
<br />
To be able to resume after suspending the computer to disk (hibernate), it is required to keep the swap filesystem intact. Therefore, it is required to have a pre-existent LUKS swap partition, which can be stored on the disk or input manually at startup. Because the resume takes place before {{ic|/etc/crypttab}} can be used, it is required to create a hook in {{ic|/etc/mkinitcpio.conf}} to open the swap LUKS device before resuming.<br />
<br />
If you want to use a partition which is currently used by the system, you have to disable it first:<br />
# swapoff /dev/<device><br />
<br />
Also make sure you remove any line in {{ic|/etc/crypttab}} pointing to this device.<br />
<br />
A simple way to realize encrypted swap with suspend-to-disk support is by using [[LVM]] ontop the encryption layer, so one encrypted partition can contain infinite filesystems (root, swap, home, ...). Follow the instructions on [[#Encrypting a LVM setup]].<br />
<br />
The following setup has the disadvantage of having to insert an additional passphrase for the swap partition manually on every boot.<br />
<br />
{{Warning|Do not use this setup with a key file. Please read about the issue reported [[Talk:System Encryption with LUKS for dm-crypt#Suspend to disk instructions are insecure|here]]}}<br />
<br />
To format the encrypted container for the swap partition, follow steps similar to those described in [[#Configuring LUKS]] above and create keyslot for a user-memorizable passphrase.<br />
<br />
Open the partition in {{ic|/dev/mapper}}:<br />
# cryptsetup luksOpen /dev/<device> swapDevice<br />
<br />
Create a swap filesystem inside the mapped partition:<br />
# mkswap /dev/mapper/swapDevice<br />
<br />
Now you have to create a hook to open the swap at boot time.<br />
<br />
* Create a hook file containing the open command:<br />
<br />
{{hc|/lib/initcpio/hooks/openswap|<nowiki><br />
# vim: set ft=sh:<br />
run_hook ()<br />
{<br />
cryptsetup luksOpen /dev/<device> swapDevice<br />
}<br />
</nowiki>}}<br />
<br />
for opening the swap device by typing your password or<br />
<br />
{{hc|/lib/initcpio/hooks/openswap|<nowiki><br />
# vim: set ft=sh:<br />
run_hook ()<br />
{<br />
mkdir crypto_key_device<br />
mount /dev/mapper/<root-device> crypto_key_device<br />
cryptsetup luksOpen --key-file crypto_key_device/<path-to-the-key> /dev/<device> swapDevice<br />
umount crypto_key_device<br />
}<br />
</nowiki>}}<br />
<br />
for opening the swap device by loading a keyfile from a crypted root device<br />
<br />
{{Note|If swap is on a Solid State Disk (SSD) and Discard/TRIM is desired the option {{ic|--allow-discards}} has to get added to the cryptsetup line in the openswap hook above. See [[#Discard.2FTRIM_support_for_solid_state_disks_.28SSD.29|Discard/TRIM support for solid state disks (SSD)]] or [[SSD]] for more information on discard. Additionally you have to add the mount option 'discard' to your fstab entry for the swap device.''}}<br />
<br />
* Then create and edit the hook setup file:<br />
{{hc|/lib/initcpio/install/openswap|<nowiki><br />
# vim: set ft=sh:<br />
build ()<br />
{<br />
add_runscript<br />
}<br />
help ()<br />
{<br />
cat<<HELPEOF<br />
This opens the swap encrypted partition /dev/<device> in /dev/mapper/swapDevice<br />
HELPEOF<br />
}<br />
</nowiki>}}<br />
<br />
* Add the hook {{ic|openswap}} in the {{ic|HOOKS}} array in {{ic|/etc/mkinitcpio.conf}}, before {{ic|filesystem}} but after {{ic|encrypt}}. Do not forget to add the {{ic|resume}} hook after {{ic|openswap}}.<br />
<nowiki>HOOKS="... encrypt openswap resume filesystems ..."</nowiki><br />
* Regenerate the boot image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
* Add the mapped partition to {{ic|/etc/fstab}} by adding the following line:<br />
/dev/mapper/swapDevice swap swap defaults 0 0<br />
<br />
* Set up your system to resume from {{ic|/dev/mapper/swapDevice}}. For example, if you use [[GRUB]] with kernel hibernation support, add {{ic|resume<nowiki>=</nowiki>/dev/mapper/swapDevice}} to the kernel line in {{ic|/boot/grub/grub.cfg}}. A line with encrypted root and swap partitions can look like this:<br />
<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice root=/dev/mapper/rootDevice resume=/dev/mapper/swapDevice ro<br />
<br />
To make the parameter persistent on kernel updates, add it to {{ic|/etc/default/grub}}. <br />
<br />
At boot time, the {{ic|openswap}} hook will open the swap partition so the kernel resume may use it. If you use special hooks for resuming from hibernation, make sure they are placed '''after''' {{ic|openswap}} in the {{ic|HOOKS}} array. Please note that because of initrd opening swap, there is no entry for swapDevice in {{ic|/etc/crypttab}} needed in this case.<br />
<br />
==== Using a swap file for suspend-to-disk support ====<br />
A swap file can be used to reserve swap-space within an existing partition and may also be setup inside an encrypted blockdevice's partition. When resuming from a swapfile the {{ic|resume}} hook must be supplied with the passphrase to unlock the device where the swap file is located. To create it: <br />
* Choose a mapped partition (e.g. {{ic|/dev/mapper/rootDevice}}) whose mounted filesystem (e.g. {{ic|/}}) contains enough free space to create a swapfile with the desired size. <br />
<br />
* [[HOW_TO:_Create_swap_file#Swap_file_creation | Create the swap file]] (e.g. {{ic|/swapfile}}) inside the mounted filesystem of your chosen mapped partition. Be sure to activate it with {{ic|swapon}} and also add it to your {{ic|/etc/fstab}} file afterward.<br />
<br />
* Set up your system to resume from your chosen mapped partition. For example, if you use [[GRUB]] with kernel hibernation support, add {{ic|resume<nowiki>=</nowiki>}}''your chosen mapped partition'' and {{ic|resume_offset<nowiki>=</nowiki>}}''see calculation command below'' to the kernel line in {{ic|/boot/grub/grub.cfg}}. A line with encrypted root partition can look like this:<br />
<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice resume=/dev/mapper/rootDevice resume_offset=123456789 ro<br />
<br />
The {{ic|resume_offset}} of the swap-file points to the start (extent zero) of the file and can be identified like this:<br />
<br />
# filefrag -v /swapfile | awk '{if($1==0){print $3}}'<br />
<br />
* Add the {{ic|resume}} hook to your {{ic|etc/mkinitcpio.conf}} file and [[Mkinitcpio#Image_creation_and_activation|rebuild the image]] afterward:<br />
<br />
HOOKS="... encrypt '''resume''' ... filesystems ..."<br />
<br />
* If you use a USB keyboard to enter your decryption password, then the {{ic|keyboard}} module '''must''' appear in front of the {{ic|encrypt}} hook, as shown below. Otherwise, you will not be able to boot your computer because you couldn't enter your decryption password to decrypt your Linux root partition!<br />
<br />
HOOKS="... '''keyboard''' encrypt ..."<br />
<br />
== Installing the system ==<br />
<br />
{{Note | Most of the installation can be carried out normally. However, there are a few areas where it is important to make certain selections. These are marked below.}}<br />
<br />
=== Prepare hard drive for Arch Install Scripts ===<br />
<br />
This assumes you want to install an encrypted system with the Arch Install Scripts, have created partitions for {{ic|/}} (e.g. {{ic|/dev/sdaX}}) and {{ic|/boot}} ({{ic|/dev/sdaY}}) at least, following the [[Installation_Guide|Installation Guide]] and deciding against [[LUKS#LVM:_Logical_Volume_Manager|using LVM]]. Prior to creating the partitions you have done a [[LUKS#Secure_erasure_of_the_hard_disk_drive|preparation]] of the disk for encryption according to your necessities (the necessary tools are on the installation-ISO). <br />
<br />
First check, if the blockdevice mapper {{ic|dm_mod}} is loaded with <br />
# lsmod | grep mod <br />
If one wants to use the default LUKS-cipher algorithm, there is no need to specify one for the luksFormat. You may want to check the [[LUKS#Using_LUKS_to_Format_Partitions_with_a_Passphrase|defaults]] used by the cryptsetup version at time of installation and decide yourself. With defaults a dm-crypt/LUKS blockdevice for the crypted root can be created <br />
# cryptsetup -y -v luksFormat /dev/sdaX<br />
opened<br />
# cryptsetup open /dev/sdaX cryptroot<br />
formatted with your desired filesystem<br />
# mkfs -t ext4 /dev/mapper/cryptroot<br />
and mounted<br />
# mount -t ext4 /dev/mapper/cryptroot /mnt<br />
<br />
At this point, just before installing the base system, it might be useful to check the mapping works as intended:<br />
# umount /mnt<br />
# cryptsetup close cryptroot<br />
and mount it again to check.<br />
<br />
If you created a separate {{ic|/home}} partition, the steps have to be adapted and repeated for that.<br />
What you do have to setup is a non-encrypted {{ic|/boot}} partition, which is needed for a crypted root. For a standard [[EFI|MBR/non-EFI]] {{ic|/boot}} partition that may be achieved by formatting<br />
# mkfs -t ext2 /dev/sdaY<br />
creating a mount-point for installation<br />
# mkdir /mnt/boot<br />
and mounting it<br />
# mount -t ext2 /dev/sdaY /mnt/boot<br />
<br />
That is basically what is necessary at this point before installing the base system with the [[Installation_Guide#Mount_the_partitions|Arch Install Scripts]]. Take care to install the bootloader to {{ic|/mnt/boot}} with the {{ic|pacstrap}} script. Additional configuration steps must be followed before booting the installed system.<br />
<br />
=== Configure initramfs ===<br />
One important point is to add the hooks relevant for your particular install in the correct order to {{ic|/etc/mkinitcpio.conf}}. The one you ''have'' to add when encrypting the root filesystem is {{ic|encrypt}}. A recommended hook for LUKS encrypted blockdevices is {{ic|shutdown}} to ensure controlled unmounting during system shutdown. Others needed, e.g. {{ic|keymap}}, should be clear from other manual steps you follow during the installation and further details in the following. For detailed information about initramfs configuration and available Hooks refer to [[Mkinitcpio#HOOKS]].<br />
<br />
{{Note|The {{ic|encrypt}} hook is only needed if your '''root''' partition is a ''LUKS'' partition (or a LUKS partition that needs to be mounted ''before'' root). The {{ic|encrypt}} hook is not needed for any other encrypted partitions (swap, for example). System initialization scripts ({{ic|/etc/rc.sysinit}} and {{ic|/etc/crypttab}} among others) take care of those.}}<br />
<br />
It is important that the {{ic|encrypt}} hook comes ''before'' the {{ic|filesystems}} hook (in case you are using '''LVM on LUKS''', the order should be: {{ic|encrypt lvm2 filesystems}}), so make sure that your {{ic|HOOKS}} array looks something like this:<br />
{{hc|etc/mkinitcpio.conf|HOOKS<nowiki>=</nowiki>"(base udev) ... '''encrypt''' ... filesystems ..."}}<br />
<br />
If you need support for foreign keymaps for your encryption password, you have to specify the hook {{ic|keymap}} as well before {{ic|encrypt}}.<br />
<br />
If you have a USB keyboard, you will need the {{ic|keyboard}} hook. Without it, no USB keyboard will work in early userspace.<br />
<br />
In the same file, you may want to add to "MODULES" '''dm_mod''' and the filesystem types used, e.g: {{ic|MODULES<nowiki>=</nowiki>"dm_mod ext4"}}<br />
<br />
After you are done don't forget:<br />
mkinitcpio -p linux<br />
<br />
<br />
=== Kernel parameter configuration of the bootloader ===<br />
In order to enable booting an encrypted root partition, it is passed to the {{ic|encrypt}} hook with [[kernel parameters]] to be set up in the bootloader. <br />
The main parameter is '''cryptdevice''', with the following syntax:<br />
cryptdevice=<device>:<dmname><br />
; <device>: The path to the raw encrypted device. Usage of [[Persistent block device naming]] is advisable.<br />
; <dmname>: The name given to the device after decryption, will be available as {{ic|/dev/mapper/<dmname>}}. (<dmname> '''MUST NOT''' be set to a name already used for LVM partitions!)<br />
<br />
So if the encrypted root device in the example is {{ic|/dev/sda2}} and the decrypted one should be mapped to {{ic|/dev/mapper/cryptroot}}, the kernel parameter would be:<br />
cryptdevice=/dev/sda2:cryptroot<br />
This will make the system prompt for the passphrase to unlock the root device on a cold boot. <br />
<br />
Depending on the setup other parameters are required as well:<br />
cryptdevice=<device>:<dmname> root=<device> resume=<device> cryptkey=<device>:<fstype>:<path><br />
<br />
; root=<device>: The device file of the actual (decrypted) root filesystem. If the filesystem is formatted directly on the decrypted device file this will be {{ic|/dev/mapper/<dmname>}}. If LVM is used, the device must be addressed like {{ic|/dev/mapper/<volgroup>-<pvol>}} or {{ic|/dev/<volgroup>/<pvol>}}.<br />
; resume=<device>: The device file of the decrypted (swap) filesystem used for suspend2disk.<br />
; cryptkey=<nowiki><device>:<fstype>:<path></nowiki>: Required for reading a [[#Storing_the_Key_File|keyfile]] from a filesystem.<br />
<br />
The syntax for the optional '''cryptkey''' parameter is:<br />
<br />
cryptkey=<device>:<fstype>:<path><br />
<br />
; <device>: The raw block device where the key exists.<br />
; <fstype>: The filesystem type of <device> (or auto).<br />
; <path>: The absolute path of the keyfile within the device.<br />
<br />
Examples on configuration for [[GRUB#Root Encryption|GRUB]] and [[Syslinux#Basic Config|Syslinux]] are available on the respective pages.<br />
<br />
=== Fstab ===<br />
Further, double-check the {{ic|gen[[fstab]]}} scripts result for your {{ic|/dev/mapper/cryptroot}} and other mounts.<br />
<br />
=== AIF Instructions ===<br />
{{Deletion|}}<br />
{{Out of date|AIF (Arch Installation Framework; referenced below also as {{ic|/arch/setup}}) does not exist anymore, GRUB Legacy is not available anymore}}<br />
==== Prepare hard drive for AIF ====<br />
<br />
Now that {{ic|/dev/mapper/root}} and {{ic|/dev/mapper/home}} are in place, we can enter the regular Arch setup script to install the system into the encrypted volumes.<br />
# /arch/setup<br />
Skip the Partitioning and Auto-Prepare steps and go straight to manual configuration.<br />
Instead of choosing the hardware devices ({{ic|/dev/sdaX}}) directly, you have to select the mapper devices created above.<br />
Choose {{ic|/dev/mapper/root}} for your root and {{ic|/dev/mapper/home}} as {{ic|/home}} partition respectively and format them with any filesystem you like.<br />
The same is valid for a swap partition which is set up like the {{ic|/home}} partition. Make sure you mount {{ic|/dev/sda1}} as the {{ic|/boot}} partition, or else the installer will not properly set up the bootloader.<br />
<br />
==== Select and Install packages ====<br />
Select and install the packages as usual: the base package contains all required programs.<br />
<br />
==== Exit Install ====<br />
Now that the install is finished the only thing left to do is add entries to the {{ic|/etc/crypttab}} file so you do not have to enter the passphrase for all encrypted partitions. This works only for non-root partitions e.g. {{ic|/home}}, swap, etc.<br />
# vi /mnt/etc/crypttab<br />
<br />
Add one of the following for the {{ic|/home}} partition.<br />
{{Note|Using a passphrase to decrypt LUKS partitions automatically from {{ic|/etc/crypttab}} is deprecated: see http://www.mail-archive.com/arch-projects@archlinux.org/msg02115.html}}<br />
home /dev/sda5 /etc/mypassword1<br />
<br />
You can also use a keyfile instead of a passphrase. If not already done, create a keyfile and add the key to the corresponding LUKS partition as described [[#Adding_Additional_Passphrases_or_Keyfiles_to_a_LUKS_Encrypted_Partition|above]].<br />
Then add the following information to the {{ic|/etc/crypttab}} file for automounting:<br />
home /dev/sda5 /path/of/your/keyfile<br />
<br />
If you used a USB device to store your keyfile, you should have something like this:<br />
home /dev/sda5 /dev/sd*1/keyfile<br />
<br />
Or if the keyfile was stored in the MBR, it should be like this:<br />
home /dev/sda5 /dev/sd*:2048:2048<br />
<br />
{{Box BLUE|Note:|When reading the keyfile from the MBR it should be {{ic|/dev/sdb}} not {{ic|/dev/sdb1}} but if the key is in the filesystem it should still be {{ic|/dev/sdb1}}.}}<br />
<br />
After rebooting you should now be presented with the text<br />
A password is required to access the root filesystem:<br />
followed by a prompt for a LUKS password. Type it in and everything should boot.<br />
Once you have logged in, have a look at your mounted partitions by typing {{ic|mount}}. You should have {{ic|/dev/mapper/root}} mounted at {{ic|/}} and, if you set up a separate encrypted home partition, {{ic|/dev/mapper/home}} mounted at {{ic|/home}}. If you set up encrypted swap, {{ic|swapon -s}} should have {{ic|/dev/mapper/swap}} listed as your swap partition.<br />
<br />
{{Note|Eventually the text prompting for the password is mixed up with other boot messages. So the boot process may seem frozen at first glance, but it is not, simply enter your password and press {{keypress|Enter}}.}}<br />
<br />
==== GRUB Legacy ====<br />
{{Out of date|Like AIF in this section, GRUB Legacy and LILO are dropped. }}<br />
'''[[GRUB Legacy]]:''' You have to make some small changes to the entries generated by the installer by replacing {{ic|/dev/mapper/root}} with {{ic|/dev/sda3}}. The important point to remember here is to use the same {{ic|cryptdevice}} name you assigned when you initially unlocked your device. In this example, the device name is {{ic|cryptroot}}; customize yours accordingly:<br />
<br />
# (0) Arch Linux<br />
title Arch Linux<br />
root (hd0,0)<br />
kernel /vmlinuz-linux cryptdevice=/dev/sda3:cryptroot root=/dev/mapper/cryptroot ro<br />
initrd /initramfs-linux.img<br />
<br />
For kernels older than 2.6.37, the syntax is:<br />
# (0) Arch Linux<br />
title Arch Linux<br />
root (hd0,0)<br />
kernel /vmlinuz26 root=/dev/sda3 ro<br />
initrd /kernel26.img<br />
<br />
==== LILO ====<br />
'''LILO:''' Edit the Arch Linux section in {{ic|/etc/lilo.conf}} and include a line for the {{ic|append}} option, over the initrd, with the {{ic|root<nowiki>=</nowiki>/dev/sda3}} parameter. The {{ic|append}} section makes the same kernel line as in GRUB. Also, you can omit the {{ic|root}} option above the {{ic|image}} option. The section looks like this:<br />
# Arch Linux lilo section<br />
image = /vmlinuz-linux<br />
# root = /dev/sda3<br />
label = Arch<br />
initrd = /initramfs-linux.img<br />
append = "root=/dev/sda3"<br />
read-only<br />
<br />
If you want to use a USB flash drive with a keyfile, you have to append the {{ic|cryptkey}} option. See the corresponding section above.<br />
<br />
== Remote unlocking of the root (or other) partition ==<br />
If you want to be able to reboot a fully LUKS-encrypted system remotely, or start it with a Wake-on-LAN service, you will need a way to enter a passphrase for the root partition/volume at startup. This can be achieved by running the {{ic|net}} hook along with an [[SSH]] server in initrd. Install the {{AUR|dropbear_initrd_encrypt}} package from the [[Arch User Repository|AUR]] and follow the post-installation instructions. Replace the {{ic|encrypt}} hook with {{ic|dropbear encryptssh}} in {{ic|/etc/mkinitcpio.conf}}. Put the {{ic|net}} hook early in the HOOKS array if your DHCP server takes a long time to lease IP addresses.<br />
<br />
If you would simply like a nice solution to mount other encrypted partitions (such as {{ic|/home}})remotely, you may want to look at [https://bbs.archlinux.org/viewtopic.php?pid=880484 this forum thread].<br />
<br />
== Backup the cryptheader ==<br />
If the header of your encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much as a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. A damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table.<br />
<br />
Therefore, having a backup of the headers and storing them on another disk might be a good idea.<br />
<br />
'''Attention:''' Many people recommend NOT backing up the cryptheader, but even so it's a single point of failure!<br />
In short, the problem is that LUKS is not aware of the duplicated cryptheader, which contains the master key which is used to encrypt all files on your partition. Of course this master key is encrypted with your passphrases or keyfiles.<br />
But if one of those gets compromised and you want to revoke it you have to do this on all copies of the cryptheader!<br />
I.e. if someone has got your cryptheader and one of your keys he can decrypt the master key and access all your data.<br />
Of course the same is true for all backups you create of your partions.<br />
So you decide if you are one of those paranoids brave enough to go without a backup for the sake of security or not.<br />
See also the [http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions#6._Backup_and_Data_Recovery| LUKS FAQ] for further details on this.<br />
<br />
=== Backup ===<br />
==== Using cryptsetup ====<br />
Cryptsetups {{ic|luksHeaderBackup}} action stores a binary backup of the LUKS header and keyslot area:<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /mnt/<backup>/<file>.img<br />
where <device> is the partition containing the LUKS volume.<br />
<br />
{{Note|Using {{ic|-}} as header backup file writes to a file named {{ic|-}}.}}<br />
<br />
{{Tip|You can also back up the plaintext header into ramfs and encrypt it in example with gpg before writing to persistent backup storage by executing the following commands.}}<br />
{{bc|# mkdir /root/<tmp>/<br />
# mount ramfs /root/<tmp>/ -t ramfs<br />
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /root/<tmp>/<file>.img<br />
# gpg2 --recipient <User ID> --encrypt /root/<tmp>/<file>.img <br />
# cp /root/<tmp>/<file>.img.gpg /mnt/<backup>/<br />
# umount /root/<tmp>}}<br />
{{Warning|Tmpfs can swap to harddisk if low on memory so it is not recommended here.}}<br />
<br />
==== Manually ====<br />
First you have to find out the payload offset of the crypted partition:<br />
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki> grep "Payload offset"|<br />
Payload offset: 4040}}<br />
Second check the sector size of the drive<br />
{{hc|# fdisk -l /dev/<device> <nowiki>|</nowiki>grep "Sector size"|Sector size (logical/physical): 512 bytes / 512 bytes}}<br />
<br />
Now that you know the values, you can backup the header with a simple dd command:<br />
# dd if=/dev/<device> of=/path/to/<file>.img bs=512 count=4040<br />
and store it safely.<br />
<br />
=== Restore ===<br />
Be careful before restore: make sure that you chose the right partition (again replace sdaX with the corresponding partition).<br />
Restoring the wrong header or restoring to an unencrypted partition will cause data loss.<br />
<br />
==== Using cryptsetup ====<br />
Or you can use the luksHeaderRestore command:<br />
cryptsetup luksHeaderRestore /dev/sdaX --header-backup-file ./backup.img<br />
<br />
'''Note:''' All the keyslot areas are overwritten; only active keyslots from the backup file are available after issuing this command.<br />
<br />
==== Manually ====<br />
Again, you will need to the same values as when backing up:<br />
dd if=./backup.img of=/dev/sdX bs=512 count=4040<br />
<br />
== Encrypting a loopback filesystem ==<br />
''[This paragraph has been merged from another page; its consistency with the other paragraphs should be improved]''<br />
<br />
=== Preparation and mapping ===<br />
First, start by creating an encrypted container!<br />
<br />
dd if=/dev/urandom of=/bigsecret bs=1M count=10<br />
<br />
This will create the file {{ic|bigsecret}} with a size of 10 megabytes.<br />
<br />
losetup /dev/loop0 /bigsecret<br />
<br />
This will create the device node {{ic|/dev/loop0}}, so that we can mount/use our container.<br />
<br />
{{Note|If it gives you the error {{ic|/dev/loop0: No such file or directory}}, you need to first load the kernel module with {{ic|modprobe loop}}. These days (Kernel 3.2) loop devices are created on demand. Ask for a new loop device with {{ic|losetup -f}}.}}<br />
<br />
cryptsetup luksFormat /dev/loop0<br />
<br />
This will ask you for a password for your new container file.<br />
<br />
{{Note|If you get an error like {{ic|Command failed: Failed to setup dm-crypt key mapping. Check kernel for support for the aes-cbc-essiv:sha256 cipher spec and verify that /dev/loop0 contains at least 133 sectors|}}, then run {{ic|modprobe dm-mod}}.}}<br />
<br />
cryptsetup luksOpen /dev/loop0 secret<br />
<br />
The encrypted container is now available through the device file {{ic|/dev/mapper/secret}}.<br />
Now we are able to create a partition in the container:<br />
<br />
mkfs.ext2 /dev/mapper/secret<br />
<br />
and mount it...<br />
<br />
mkdir /mnt/secret<br />
mount -t ext2 /dev/mapper/secret /mnt/secret<br />
<br />
We can now use the container as if it was a normal partition!<br />
To unmount the container:<br />
<br />
umount /mnt/secret<br />
cryptsetup luksClose secret<br />
losetup -d /dev/loop0 # free the loopdevice.<br />
<br />
so, if you want to mount the container again, you just apply the following commands:<br />
<br />
losetup /dev/loop0 /bigsecret<br />
cryptsetup luksOpen /dev/loop0 secret<br />
mount -t ext2 /dev/mapper/secret /mnt/secret<br />
<br />
=== Encrypt using a key-file ===<br />
Let us first generate a 2048 byte random keyfile:<br />
<br />
dd if=/dev/urandom of=keyfile bs=1k count=2<br />
<br />
We can now format our container using this key<br />
<br />
cryptsetup luksFormat /dev/loop0 keyfile<br />
<br />
or our partition : <br />
<br />
cryptsetup luksFormat /dev/hda2 keyfile<br />
<br />
Once formatted, we can now open the LUKS device using the key:<br />
<br />
cryptsetup -d keyfile luksOpen /dev/loop0 container<br />
<br />
You can now like before format the device {{ic|/dev/mapper/container}} with your favorite filesystem and then mount it just as easily.<br />
<br />
The keyfile is now the only key to your file. I personally advise encrypting your keyfile using your private GPG key and storing an off-site secured copy of the file.<br />
<br />
=== Resizing the loopback filesystem ===<br />
First we should unmount the encrypted container:<br />
umount /mnt/secret<br />
cryptsetup luksClose secret<br />
losetup -d /dev/loop0 # free the loopdevice.<br />
<br />
After this we need to expand our container file with the size of the data we want to add:<br />
<br />
dd if=/dev/urandom bs=1M count=1024 | cat - >> /bigsecret<br />
<br />
Be careful to really use TWO {{ic|>}}, or you will override your current container!<br />
<br />
You could use {{ic|/dev/zero}} instead of {{ic|/dev/urandom}} to significantly speed up the process, but with {{ic|/dev/zero}} your encrypted filesystems will ''not be as secure''. (A better option to create random data quicker than {{ic|/dev/urandom}} is {{ic|frandom}} [https://aur.archlinux.org/packages.php?ID=9869], available from the [[AUR]]).<br />
A faster (almost instant) method than dd is {{ic|truncate}} , but its use has the same security implications as using /dev/zero. The size passed to truncate is the final size to make the file, so don't use a value less than that of the current file or you will lose data. e.g. to increase a 20G file by 10G: truncate -s 30G filename.<br />
<br />
Now we have to map the container to the loop device:<br />
losetup /dev/loop0 /bigsecret<br />
cryptsetup luksOpen /dev/loop0 secret<br />
After this we will resize the encrypted part of the container to the maximum size of the container file:<br />
cryptsetup resize secret<br />
Finally, we can resize the filesystem. Here is an example for ext2/3/4:<br />
e2fsck -f /dev/mapper/secret # Just doing a filesystem check, because it's a bad idea to resize a broken fs<br />
resize2fs /dev/mapper/secret<br />
You can now mount your container again:<br />
mount /dev/mapper/secret /mnt/secret<br />
<br />
== Encrypting a LVM setup ==<br />
{{Merge|Encrypted_LVM |Device mapper stacking is explained there building on the LVM wiki with a howto for both approaches below.}}<br />
<br />
It's really easy to use encryption with [[LVM]]. If you do not know how to set up LVM, then read [[Installing with Software RAID or LVM]].<br />
<br />
'''LVM on LUKS'''<br />
<br />
The easiest and best method is to set up LVM on top of the encrypted partition instead of the other way round. This link here is easy to follow and explains everything: [http://www.pindarsign.de/webblog/?p=767 Arch Linux: LVM on top of an encrypted partition]<br />
<br />
The most important thing in setting LVM on '''top''' of encryption is to [[#Configure initramfs|configure the initramfs]] for running the {{ic|encrypt}} hook '''before''' the {{ic|lvm2}} hook (and those two before the {{ic|filesystems}} hook). <br />
<br />
'''LUKS on LVM'''<br />
<br />
To use encryption on top of LVM, you have to first set up your LVM volumes and then use them as the base for the encrypted partitions. That means, in short, that you have to set up LVM first. Then follow this guide, but replace all occurrences of {{ic|/dev/sdXy}} in the guide with its LVM counterpart. (E.g.: {{ic|/dev/sda5}} -> {{ic|/dev/<volume group name>/home}}). This is used to setup partitions (inside the LVM) which can be unlocked separately or a mixture of encrypted and non-encrypted partitions. <br />
<br />
For encrypted partitions inside an LVM, the LVM-hook has to run first, before the respective encrypted logical volumes can be unlocked. So for this add the {{ic|encrypt}} hook in {{ic|/etc/mkinitcpio.conf}} '''after''' the {{ic|lvm2}} hook, if you chose to set up encrypted partitions on '''top''' of LVM. Also remember to change {{ic|USELVM}} in {{ic|/etc/rc.conf}} to {{ic|"yes"}}. <br />
<br />
=== LVM with Arch Linux Installer (>2009.08 <2012.07.15) ===<br />
{{Out of date|As of the [https://www.archlinux.org/news/install-media-20120715-released/ 2012.07.15 installation media release] the AIF (Arch Installation Framework) and grub-legacy are dropped. These outdated instructions still give the backbones to understanding what to do. If you plan to do a fresh install, also check the howto [[Encrypted_LVM]].}}<br />
<br />
In between Arch Linux installation media release 2009.08 and 2012.07.15 LVM and dm_crypt had been supported by the installer out of the box.<br />
This made it very easy to configure a system for [[LVM]] on dm-crypt or vice versa.<br />
Actually the configuration is done exactly as without LVM: see the [[#Arch Linux Installer (>2009.08 <2012.07.15)|corresponding]] section above. It differs only in two aspects.<br />
<br />
==== The partition and filesystem choice ====<br />
Create a small, unencrypted boot partition and use the remaining space for a single partition which can later be split up into multiple logic volumes by [[LVM]].<br />
<br />
For a LVM-on-dm-crypt system set up the filesystems and mounting points for example like this:<br />
/dev/sda1 raw->ext2;yes;/boot;no_opts;no_label;no_params<br />
/dev/sda2 raw->dm_crypt;yes;no_mountpoint;no_opts;sda2crypt;-c_aes-xts-plain_-y_-s_512<br />
/dev/mapper/sda2crypt dm_crypt->lvm-vg;yes;no_mountpoint;no_opts;no_label;no_params<br />
/dev/mapper/sda2crypt+ lvm-pv->lvm-vg;yes;no_mountpoint;no_opts;cryptpool;no_params<br />
/dev/mapper/cryptpool lvm-vg(cryptpool)->lvm-lv;yes;no_mountpoint;no_opts;cryptroot;10000M|lvm-lv;yes;no_mountpoint;no_opts;crypthome;20000M<br />
/dev/mapper/cryptpool-cryptroot lvm-lv(cryptroot)->ext3;yes;/;no_opts;cryptroot;no_params<br />
/dev/mapper/cryptpool-crypthome lvm-lv(crypthome)->ext3;yes;/home;no_opts;cryptroot;no_params<br />
<br />
==== The configuration stage ====<br />
* In {{ic|/etc/mkinitcpio.conf}} add the {{ic|encrypt}} hook '''before''' the {{ic|lvm2}} hook in the {{ic|HOOKS}} array, if you set up LVM on top of the encrypted partition.<br />
<br />
That is it for the LVM & dm_crypt specific part. The rest is done as usual.<br />
<br />
{{Accuracy|The {{ic|lvm2}} hook activates the (encrypted) root volume group long before sysvinit (or systemd) can run from there. Letting sysvinit later run a second LVM activation in addition serves no purpose. Read [[LVM#Configure system]]. However this error is duplicated within the [[#Encrypting a LVM setup]] section.}}<br />
* In {{ic|/etc/rc.conf}} set {{ic|USELVM}} to {{ic|"yes"}}.<br />
<br />
=== Applying this to a non-root partition ===<br />
You might get tempted to apply all this fancy stuff to a non-root partition. Arch does not support this out of the box, however, you can easily change the cryptdev and cryptname values in {{ic|/lib/initcpio/hooks/encrypt}} (the first one to your {{ic|/dev/sd*}} partition, the second to the name you want to attribute). That should be enough.<br />
<br />
The big advantage is you can have everything automated, while setting up {{ic|/etc/crypttab}} with an external key file (i.e. the keyfile is not on any internal hard drive partition) can be a pain - you need to make sure the USB/FireWire/... device gets mounted before the encrypted partition, which means you have to change the order of {{ic|/etc/fstab}} (at least).<br />
<br />
Of course, if the {{Pkg|cryptsetup}} package gets upgraded, you will have to change this script again. However, this solution is to be preferred over hacking {{ic|/etc/rc.sysinit}} or similar files. Unlike {{ic|/etc/crypttab}}, only one partition is supported, but with some further hacking one should be able to have multiple partitions unlocked.<br />
<br />
If you want to do this on a software RAID partition, there is one more thing you need to do. Just setting the {{ic|/dev/mdX}} device in {{ic|/lib/initcpio/hooks/encrypt}} is not enough; the {{ic|encrypt}} hook will fail to find the key for some reason, and not prompt for a passphrase either. It looks like the RAID devices are not brought up until after the {{ic|encrypt}} hook is run. You can solve this by putting the RAID array in {{ic|/boot/grub/menu.lst}}, like <br />
kernel /boot/vmlinuz-linux md=1,/dev/hda5,/dev/hdb5<br />
<br />
If you set up your root partition as a RAID, you will notice the similarities with that setup ;-). [[GRUB]] can handle multiple array definitions just fine:<br />
kernel /boot/vmlinuz-linux root=/dev/md0 ro md=0,/dev/sda1,/dev/sdb1 md=1,/dev/sda5,/dev/sdb5,/dev/sdc5<br />
<br />
=== LVM and dm-crypt manually (short version) ===<br />
<br />
==== Notes ====<br />
If you are smart enough for this, you will be smart enough to ignore/replace LVM-specific things if you do not want to use LVM.<br />
<br />
{{Note|This brief uses reiserfs for some of the partitions, so change this accordingly if you want to use a more "normal" file system, like ext4.}}<br />
<br />
==== Partitioning scheme ====<br />
{{ic|/dev/sda1}} -> {{ic|/boot}}<br />
{{ic|/dev/sda2}} -> LVM<br />
<br />
==== The commands ====<br />
cryptsetup -d /dev/random -c aes-xts-plain -s 512 create lvm /dev/sda2<br />
dd if=/dev/urandom of=/dev/mapper/lvm<br />
cryptsetup remove lvm<br />
lvm pvcreate /dev/sda2<br />
lvm vgcreate lvm /dev/sda2<br />
lvm lvcreate -L 10G -n root lvm<br />
lvm lvcreate -L 500M -n swap lvm<br />
lvm lvcreate -L 500M -n tmp lvm<br />
lvm lvcreate -l 100%FREE -n home lvm<br />
cryptsetup luksFormat -c aes-xts-plain -s 512 /dev/lvm/root<br />
cryptsetup luksOpen /dev/lvm/root root<br />
mkreiserfs /dev/mapper/root<br />
mount /dev/mapper/root /mnt<br />
dd if=/dev/zero of=/dev/sda1 bs=1M<br />
mkreiserfs /dev/sda1<br />
mkdir /mnt/boot<br />
mount /dev/sda1 /mnt/boot<br />
mkdir -p -m 700 /mnt/etc/luks-keys<br />
dd if=/dev/random of=/mnt/etc/luks-keys/home bs=1 count=256<br />
<br />
==== Install Arch Linux ====<br />
Run {{ic|/arch/setup}}<br />
<br />
==== Configuration ====<br />
<br />
===== /etc/rc.conf =====<br />
Change {{ic|USELVM<nowiki>=</nowiki>"no"}} to {{ic|USELVM<nowiki>=</nowiki>"yes"}}.<br />
<br />
===== /etc/mkinitcpio.conf =====<br />
Put {{ic|lvm2}} and {{ic|encrypt}} (in that order) before {{ic|filesystems}} in the {{ic|HOOKS}} array. Again, note that you are setting encryption on '''top''' of LVM.)<br />
<br />
if you want install the system on a usb stick, you need to put {{ic|usb}} just after {{ic|udev}}.<br />
<br />
===== /boot/grub/menu.lst =====<br />
Change {{ic|root<nowiki>=</nowiki>/dev/hda3}} to {{ic|root<nowiki>=</nowiki>/dev/lvm/root}}.<br />
<br />
For kernel >= 2.6.30, you should change {{ic|root<nowiki>=</nowiki>/dev/hda3}} to the following:<br />
cryptdevice=/dev/lvm/root:root root=/dev/mapper/root<br />
<br />
if you want install the system on a usb stick, you need to add {{ic|lvmdelay<nowiki>=</nowiki>/dev/mapper/lvm-root}}<br />
<br />
===== /etc/fstab =====<br />
/dev/mapper/root / reiserfs defaults 0 1<br />
/dev/sda1 /boot reiserfs defaults 0 2<br />
/dev/mapper/tmp /tmp tmpfs defaults 0 0<br />
/dev/mapper/swap none swap sw 0 0<br />
<br />
===== /etc/crypttab =====<br />
<br />
swap /dev/lvm/swap SWAP -c aes-xts-plain -h whirlpool -s 512<br />
tmp /dev/lvm/tmp /dev/urandom -c aes-xts-plain -s 512<br />
<br />
==== After rebooting ====<br />
<br />
===== The commands =====<br />
cryptsetup luksFormat -c aes-xts-plain -s 512 /dev/lvm/home /etc/luks-keys/home<br />
cryptsetup luksOpen -d /etc/luks-keys/home /dev/lvm/home home<br />
mkreiserfs /dev/mapper/home<br />
mount /dev/mapper/home /home<br />
<br />
===== /etc/crypttab =====<br />
home /dev/lvm/home /etc/luks-keys/home<br />
<br />
===== /etc/fstab =====<br />
/dev/mapper/home /home reiserfs defaults 0 0<br />
<br />
=== / on LVM on LUKS ===<br />
Make sure your kernel command line looks like this:<br />
root=/dev/mapper/<volume-group>-<logical-volume> cryptdevice=/dev/<luks-part>:<volume-group><br />
For example:<br />
root=/dev/mapper/vg-arch cryptdevice=/dev/sda4:vg<br />
<br />
Or like this:<br />
cryptdevice=/dev/<volume-group>/<logical-volume>:root root=/dev/mapper/root<br />
<br />
==Using GPG or OpenSSL Encrypted Keyfiles==<br />
The following forum posts give instructions to use two factor authentication, gpg or openssl encrypted keyfiles, instead of a plaintext keyfile described earlier in this wiki article [https://bbs.archlinux.org/viewtopic.php?id=120243 System Encryption using LUKS with GPG encrypted keys]:<br />
* GnuPG: [https://bbs.archlinux.org/viewtopic.php?pid=943338#p943338 Post regarding GPG encrypted keys] This post has the generic instructions.<br />
* OpenSSL: [https://bbs.archlinux.org/viewtopic.php?pid=947805#p947805 Post regarding OpenSSL encrypted keys] This post only has the {{ic|ssldec}} hooks.<br />
* OpenSSL: [https://bbs.archlinux.org/viewtopic.php?id=155393 Post regarding OpenSSL salted bf-cbc encrypted keys] This post has the {{ic|bfkf}} initcpio hooks, install, and encrypted keyfile generator scripts.<br />
<br />
Note that:<br />
* You can follow the above instructions with only two primary partitions one boot partition <br />
(required because of LVM), and one primary LVM partition. Within the LVM partition you can have <br />
as many partitions as you need, but most importantly it should contain at least root, swap, and <br />
home logical volume partitions. This has the added benefit of having only one keyfile for all <br />
your partitions, and having the ability to hibernate your computer (suspend to disk) where the <br />
swap partition is encrypted. If you decide to do so your hooks in {{ic|/etc/mkinitcpio.conf}} <br />
should look like<br />
{{ic|HOOKS&#61;" ... usb usbinput (etwo or ssldec) encrypt(if using openssl) lvm2 resume ... "}}<br />
and you should add {{ic|"resume&#61;/dev/mapper/<VolumeGroupName>-<LVNameOfSwap>"}} to your [[kernel parameters]].<br />
* If you need to temporarily store the unecrypted keyfile somewhere, do not store them on an <br />
unencrytped disk. Even better make sure to store them to RAM such as {{ic|/dev/shm}}.<br />
* If you want to use a GPG encrypted keyfile, you need to use a statically compiled GnuPG version 1.4 or you could edit the hooks and use this AUR package [https://aur.archlinux.org/packages.php?ID=58030 gnupg1]<br />
* It is possible that an update to OpenSSL could break the custom {{ic|ssldec}} mentioned in the second forum post.<br />
<br />
==Securing the unencrypted boot partition==<br />
Referring to an article from the ct-magazine (Issue 3/12, page 146, 01.16.2012 http://www.heise.de/ct/inhalt/2012/03/6/) the following script checks all files under {{ic|/boot}} for changes of SHA-1 hash, inode and occupied blocks on the hard drive. It also checks the MBR.<br />
<br />
The script with installation instructions is available here: ftp://ftp.heise.de/pub/ct/listings/1203-146.zip (Author: Juergen Schmidt, ju at heisec.de; License: GPLv2). There is also an AUR package: {{AUR|chkboot}}<br />
<br />
After installation:<br />
* For classical sysvinit: add {{ic|/usr/local/bin/chkboot.sh &}} to your {{ic|/etc/rc.local}}<br />
* For systemd: add a service file and enable the service: [[systemd]]. The service file might look like:<br />
[Unit]<br />
Description=Check that boot is what we want<br />
Requires=basic.target<br />
After=basic.target<br />
<br />
[Service]<br />
Type=oneshot<br />
ExecStart=/usr/local/bin/chkboot.sh<br />
<br />
[Install]<br />
WantedBy=multi-user.target<br />
<br />
There is a small caveat for systemd: At the time of writing the original {{ic|chkboot.sh}} script provided contains an empty space at the beginning of {{ic|<u> </u>#!/bin/bash}} which has to be removed for the service to start successfully.<br />
<br />
As {{ic|/usr/local/bin/chkboot_user.sh}} need to be excuted after login, add it to the autostart (e.g. under KDE -> System Settings -> Startup and Shutdown -> Autostart; Gnome3: gnome-session-properties). <br />
<br />
With Arch Linux changes to {{ic|/boot}} are pretty frequent, for example by new kernels rolling-in. Therefore it may be helpful to use the scripts with every full system update. One way to do so: <br />
<br />
#!/bin/bash<br />
#<br />
# Note: Insert your <user> and execute it with sudo for pacman & chkboot to work automagically<br />
#<br />
echo "Pacman update [1] Quickcheck before updating" & <br />
sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user> <br />
/usr/local/bin/chkboot.sh<br />
sync # sync disks with any results <br />
sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user> <br />
echo "Pacman update [2] Syncing repos for pacman" <br />
pacman -Syu<br />
/usr/local/bin/chkboot.sh<br />
sync <br />
sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user><br />
echo "Pacman update [3] All done, let's roll on ..."<br />
<br />
== Automount user homes on login ==<br />
See [[Pam mount]].<br />
<br />
== Resources ==<br />
* [http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions cryptsetup FAQ] - The main and foremost help resource, directly from the developers.<br />
* [http://www.freeotfe.org/ FreeOTFE] - Supports unlocking LUKS encrypted volumes in Microsoft Windows.<br />
<br />
<br />
{{Out of date|Explained separately for each link beneath.}}<br />
* [http://vimeo.com/40694871 Arch cryptsetup example video] - A HowTo video on setting up an encrypted Arch system from scratch. The video still shows an installation with AIF, which is at the time of writing deprecated / not developed further. The important partitioning and cryptsetup are shown outside AIF though.<br />
* [http://yannickloth.be/blog/2010/08/01/installing-archlinux-with-software-raid1-encrypted-filesystem-and-lvm2/ Install Arch Linux on top of RAID1, LVM2, and encrypted partitions] - The HowTo instructs to make a full Fedora 13 Install only to set up the mapping. Then legacy AIF is used.</div>Chehri