diff options
Diffstat (limited to 'security/opkssh')
| -rw-r--r-- | security/opkssh/Makefile | 50 | ||||
| -rw-r--r-- | security/opkssh/distinfo | 5 | ||||
| -rw-r--r-- | security/opkssh/files/patch-commands_readhome.go | 11 | ||||
| -rw-r--r-- | security/opkssh/files/patch-main.go | 91 | ||||
| -rw-r--r-- | security/opkssh/files/patch-policy_enforcer.go | 11 | ||||
| -rw-r--r-- | security/opkssh/files/patch-policy_policyloader.go | 11 | ||||
| -rw-r--r-- | security/opkssh/files/pkg-message.in | 22 | ||||
| -rw-r--r-- | security/opkssh/pkg-descr | 8 |
8 files changed, 209 insertions, 0 deletions
diff --git a/security/opkssh/Makefile b/security/opkssh/Makefile new file mode 100644 index 000000000000..36c50d9ac217 --- /dev/null +++ b/security/opkssh/Makefile @@ -0,0 +1,50 @@ +PORTNAME= opkssh +DISTVERSIONPREFIX= v +DISTVERSION= 0.10.0 +CATEGORIES= security +MASTER_SITES= LOCAL/dtxdf/${PORTNAME}/ +DISTFILES= ${PORTNAME}-${DISTVERSIONPREFIX}${DISTVERSION}.vendor${EXTRACT_SUFX} + +MAINTAINER= dtxdf@FreeBSD.org +COMMENT= Tool which enables SSH to be used with OpenID Connect + +LICENSE= APACHE20 +LICENSE_FILE= ${WRKSRC}/LICENSE + +USES= go:1.23,modules +USE_GITHUB= yes +GH_ACCOUNT= openpubkey +GO_BUILDFLAGS= -ldflags "-X main.Version=${DISTVERSIONPREFIX}${DISTVERSION}" + +SUB_FILES= pkg-message +SUB_LIST= GROUP=${OPKSSH_GROUP} \ + USER=${OPKSSH_USER} + +USERS= ${OPKSSH_USER} +GROUPS= ${OPKSSH_GROUP} + +PLIST_FILES= bin/${PORTNAME} + +OPKSSH_USER= opksshuser +OPKSSH_GROUP= ${OPKSSH_USER} + +post-extract: + @${MKDIR} ${WRKSRC}/vendor + @cd ${WRKDIR}/${PORTNAME}-vendor && ${COPYTREE_SHARE} . ${WRKSRC}/vendor + +# To generate the following patches: +# - make extract +# - cd ${WRKSRC} +# - rg '/etc' | cut -d: -f1 | sort | uniq | grep -Ee '.+\.go$' | grep -vEe '_test\.go$' | xargs -I % cp % %.orig +# - rg '/etc' | cut -d: -f1 | sort | uniq | grep -Ee '.+\.go$' | grep -vEe '_test\.go$' | xargs -L1 sed -i '' -Ee 's,/etc,%%PREFIX%%/etc,g' +# - cd - +# - make makepatch +# - rm ${FILESDIR}/files/patch-vendor_g* +# - Some replaced strings are just comments, so it's ok to leave them there, +# but I'll remove them anyway to avoid unnecessary patches, so check each +# file in FILESDIR. +post-patch: + @${GREP} -Flr %%PREFIX%% ${WRKSRC} | ${XARGS} ${REINPLACE_CMD} \ + 's,%%PREFIX%%,${PREFIX},g' + +.include <bsd.port.mk> diff --git a/security/opkssh/distinfo b/security/opkssh/distinfo new file mode 100644 index 000000000000..1569d7666eb9 --- /dev/null +++ b/security/opkssh/distinfo @@ -0,0 +1,5 @@ +TIMESTAMP = 1763233259 +SHA256 (opkssh-v0.10.0.vendor.tar.gz) = 038566589aa4db1bd890b20e074d0b9b995a2b766b30c72f97b35dd2afa4168e +SIZE (opkssh-v0.10.0.vendor.tar.gz) = 5490704 +SHA256 (openpubkey-opkssh-v0.10.0_GH0.tar.gz) = 71796c060705411e98fc7d11d944c531cea1d09df14cc1331c5647a31483de41 +SIZE (openpubkey-opkssh-v0.10.0_GH0.tar.gz) = 573801 diff --git a/security/opkssh/files/patch-commands_readhome.go b/security/opkssh/files/patch-commands_readhome.go new file mode 100644 index 000000000000..402b3d09f72e --- /dev/null +++ b/security/opkssh/files/patch-commands_readhome.go @@ -0,0 +1,11 @@ +--- commands/readhome.go.orig 2025-11-15 19:19:27 UTC ++++ commands/readhome.go +@@ -14,7 +14,7 @@ + // + // SPDX-License-Identifier: Apache-2.0 + +-//go:build linux || darwin ++//go:build linux || darwin || freebsd + + package commands + diff --git a/security/opkssh/files/patch-main.go b/security/opkssh/files/patch-main.go new file mode 100644 index 000000000000..9f8d47b12023 --- /dev/null +++ b/security/opkssh/files/patch-main.go @@ -0,0 +1,91 @@ +--- main.go.orig 2025-09-11 18:38:37 UTC ++++ main.go +@@ -80,7 +80,7 @@ This program allows users to: + Short: "Appends new rule to the policy file", + Long: `Add appends a new policy entry in the auth_id policy file granting SSH access to the specified email or subscriber ID (sub) or group. + +-It first attempts to write to the system-wide file (/etc/opk/auth_id). If it lacks permissions to update this file it falls back to writing to the user-specific file (~/.opk/auth_id). ++It first attempts to write to the system-wide file (%%PREFIX%%/etc/opk/auth_id). If it lacks permissions to update this file it falls back to writing to the user-specific file (~/.opk/auth_id). + + Arguments: + PRINCIPAL The target user account (requested principal). +@@ -217,7 +217,7 @@ You should not call this command directly. It is calle + SilenceUsage: true, + Use: "verify <PRINCIPAL> <CERT> <KEY_TYPE>", + Short: "Verify an SSH key (used by sshd AuthorizedKeysCommand)", +- Long: `Verify extracts a PK token from a base64-encoded SSH certificate and verifies it against policy. It expects an allowed provider file at /etc/opk/providers and a user policy file at either /etc/opk/auth_id or ~/.opk/auth_id. ++ Long: `Verify extracts a PK token from a base64-encoded SSH certificate and verifies it against policy. It expects an allowed provider file at %%PREFIX%%/etc/opk/providers and a user policy file at either %%PREFIX%%/etc/opk/auth_id or ~/.opk/auth_id. + + This command is intended to be called by sshd as an AuthorizedKeysCommand: + https://man.openbsd.org/sshd_config#AuthorizedKeysCommand +@@ -233,8 +233,8 @@ Verification checks performed: + + Verification checks performed: + 1. Ensures the PK token is properly formed, signed, and issued by the specified OpenID Provider (OP). +- 2. Confirms the PK token's issue (iss) and client ID (audience) are listed in the allowed provider file (/etc/opk/providers) and the token is not expired. +- 3. Validates the identity (email or sub) in the PK token against user policies (/etc/opk/auth_id or ~/.opk/auth_id) to ensure it can assume the requested username (principal). ++ 2. Confirms the PK token's issue (iss) and client ID (audience) are listed in the allowed provider file (%%PREFIX%%/etc/opk/providers) and the token is not expired. ++ 3. Validates the identity (email or sub) in the PK token against user policies (%%PREFIX%%/etc/opk/auth_id or ~/.opk/auth_id) to ensure it can assume the requested username (principal). + + If all checks pass, Verify authorizes the SSH connection. + +@@ -269,10 +269,10 @@ Arguments: + certB64Arg := args[1] + typArg := args[2] + +- providerPolicyPath := "/etc/opk/providers" ++ providerPolicyPath := "%%PREFIX%%/etc/opk/providers" + providerPolicy, err := policy.NewProviderFileLoader().LoadProviderPolicy(providerPolicyPath) + if err != nil { +- log.Println("Failed to open /etc/opk/providers:", err) ++ log.Println("Failed to open %%PREFIX%%/etc/opk/providers:", err) + return err + } + +@@ -301,7 +301,7 @@ Arguments: + } + }, + } +- verifyCmd.Flags().StringVar(&serverConfigPathArg, "config-path", "/etc/opk/config.yml", "Path to the server config file. Default: /etc/opk/config.yml.") ++ verifyCmd.Flags().StringVar(&serverConfigPathArg, "config-path", "%%PREFIX%%/etc/opk/config.yml", "Path to the server config file. Default: %%PREFIX%%/etc/opk/config.yml.") + rootCmd.AddCommand(verifyCmd) + + clientCmd := &cobra.Command{ +@@ -504,30 +504,30 @@ func detectOS() OSType { + // detectOS determines the type of operating system. + func detectOS() OSType { + // Check for RedHat-based systems +- if _, err := os.Stat("/etc/redhat-release"); err == nil { ++ if _, err := os.Stat("%%PREFIX%%/etc/redhat-release"); err == nil { + return OSTypeRHEL + } + + // Check for Debian-based systems +- if _, err := os.Stat("/etc/debian_version"); err == nil { ++ if _, err := os.Stat("%%PREFIX%%/etc/debian_version"); err == nil { + return OSTypeDebian + } + + // Check for Arch Linux +- if _, err := os.Stat("/etc/arch-release"); err == nil { ++ if _, err := os.Stat("%%PREFIX%%/etc/arch-release"); err == nil { + return OSTypeArch + } + + // Check for SUSE Linux +- if _, err := os.Stat("/etc/SuSE-release"); err == nil { ++ if _, err := os.Stat("%%PREFIX%%/etc/SuSE-release"); err == nil { + return OSTypeSUSE + } +- if _, err := os.Stat("/etc/SUSE-brand"); err == nil { ++ if _, err := os.Stat("%%PREFIX%%/etc/SUSE-brand"); err == nil { + return OSTypeSUSE + } + +- // Check for /etc/os-release which exists on most modern Linux systems +- if content, err := os.ReadFile("/etc/os-release"); err == nil { ++ // Check for %%PREFIX%%/etc/os-release which exists on most modern Linux systems ++ if content, err := os.ReadFile("%%PREFIX%%/etc/os-release"); err == nil { + contentStr := string(content) + if strings.Contains(contentStr, "ID=rhel") || + strings.Contains(contentStr, "ID=centos") || diff --git a/security/opkssh/files/patch-policy_enforcer.go b/security/opkssh/files/patch-policy_enforcer.go new file mode 100644 index 000000000000..0330f82a4251 --- /dev/null +++ b/security/opkssh/files/patch-policy_enforcer.go @@ -0,0 +1,11 @@ +--- policy/enforcer.go.orig 2025-11-15 20:20:44 UTC ++++ policy/enforcer.go +@@ -54,7 +54,7 @@ type checkedClaims struct { + } + + // The default location for policy plugins +-const pluginPolicyDir = "/etc/opk/policy.d" ++const pluginPolicyDir = "%%PREFIX%%/etc/opk/policy.d" + + // Validates that the server defined identity attribute matches the + // respective claim from the identity token diff --git a/security/opkssh/files/patch-policy_policyloader.go b/security/opkssh/files/patch-policy_policyloader.go new file mode 100644 index 000000000000..e32d18134c99 --- /dev/null +++ b/security/opkssh/files/patch-policy_policyloader.go @@ -0,0 +1,11 @@ +--- policy/policyloader.go.orig 2025-11-15 20:20:44 UTC ++++ policy/policyloader.go +@@ -29,7 +29,7 @@ import ( + + // SystemDefaultPolicyPath is the default filepath where opkssh policy is + // defined +-var SystemDefaultPolicyPath = filepath.FromSlash("/etc/opk/auth_id") ++var SystemDefaultPolicyPath = filepath.FromSlash("%%PREFIX%%/etc/opk/auth_id") + + // UserLookup defines the minimal interface to lookup users on the current + // system diff --git a/security/opkssh/files/pkg-message.in b/security/opkssh/files/pkg-message.in new file mode 100644 index 000000000000..49cc063a10ae --- /dev/null +++ b/security/opkssh/files/pkg-message.in @@ -0,0 +1,22 @@ +[ +{ type: install + message: <<EOM +Configure your sshd_config(5) with the following to use opkssh for authorization: + + AuthorizedKeysCommand %%PREFIX%%/bin/opkssh verify %u %k %t + AuthorizedKeysCommandUser %%USER%% + +opkssh uses the '%%PREFIX%%/etc/opk' directory, where providers and identities are stored. +Neither the directory nor the files are created automatically, so you must create them +yourself. After creating the 'auth_id' and 'providers' files, they must have the +following permissions: + + chown root:%%GROUP%% %%PREFIX%%/etc/opk/auth_id + chmod 640 %%PREFIX%%/etc/opk/auth_id + chown root:%%GROUP%% %%PREFIX%%/etc/opk/providers + chmod 640 %%PREFIX%%/etc/opk/providers + +Users attempting to use opkssh from jails, please add "allow.mlock" or it will not run. +EOM +} +] diff --git a/security/opkssh/pkg-descr b/security/opkssh/pkg-descr new file mode 100644 index 000000000000..8fa881cbe9e8 --- /dev/null +++ b/security/opkssh/pkg-descr @@ -0,0 +1,8 @@ +opkssh is a tool which enables ssh to be used with OpenID Connect +allowing SSH access to be managed via identities like alice@example.com +instead of long-lived SSH keys. It does not replace SSH, but instead +generates SSH public keys containing PK Tokens and configures sshd +to verify them. These PK Tokens contain standard OpenID Connect ID +Tokens. This protocol builds on the OpenPubkey which adds user +public keys to OpenID Connect without breaking compatibility with +existing OpenID Provider. |
