forked from ubccr/goipa
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
1,203 additions
and
557 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# goipa - FreeIPA client library | ||
=============================================================================== | ||
|
||
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue)](https://pkg.go.dev/github.com/ubccr/goipa) | ||
|
||
goipa is a [FreeIPA](http://www.freeipa.org/) client library written in Go. | ||
It interfaces with the FreeIPA JSON [api](https://github.com/freeipa/freeipa/blob/master/API.txt) | ||
over HTTPS. | ||
|
||
## Usage | ||
|
||
Install using go tools: | ||
|
||
``` | ||
$ go get github.com/ubccr/goipa | ||
``` | ||
|
||
Example calling FreeIPA user-show: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/ubccr/goipa" | ||
) | ||
|
||
func main() { | ||
client := ipa.NewDefaultClient() | ||
|
||
err := client.LoginWithKeytab("/path/to/user.keytab", "username") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
rec, err := client.UserShow("username") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
fmt.Println("%s - %s", rec.Username, rec.Uid) | ||
} | ||
``` | ||
|
||
## Hacking | ||
|
||
Development and testing goipa uses docker-compose. The scripts to spin up a | ||
FreeIPA test server in docker were copied/adopted from [this great repository](https://github.com/adelton/webauthinfra). | ||
Most of the scripts in `container/` directory are written by Jan Pazdziora and | ||
licensed under Apache 2.0 and modified for use with goipa. | ||
|
||
NOTE: The containers are NOT meant to be run in production and used solely for | ||
development. | ||
|
||
To get started hacking on goipa and running the test suite: | ||
|
||
``` | ||
$ cp .env.sample .env | ||
[edit to taste. add passwords and ssh key] | ||
$ docker-compose build | ||
$ docker-compose up -d | ||
$ ssh -p 9022 localhost | ||
$ kinit admin | ||
$ cd /app | ||
$ go test | ||
``` | ||
|
||
To run a specific test with trace debugging: | ||
|
||
``` | ||
$ go test -v -run UserShow | ||
``` | ||
|
||
## License | ||
|
||
goipa is released under a BSD style License. See the LICENSE file. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
FROM centos:centos7 | ||
RUN yum swap -y -- remove fakesystemd -- install systemd systemd-libs && yum clean all | ||
RUN yum install -y ipa-client openssh-server openssh-clients sudo vim vim-go wget dbus-python perl 'perl(Data::Dumper)' 'perl(Time::HiRes)' && yum clean all | ||
COPY init-data ipa-client-enroll populate-data-volume /usr/sbin/ | ||
RUN sed -i 's/^#AddressFamily any/AddressFamily inet/' /etc/ssh/sshd_config | ||
COPY ipa-client-enroll.service populate-data-volume.service /usr/lib/systemd/system/ | ||
RUN ln -s /usr/lib/systemd/system/ipa-client-enroll.service /usr/lib/systemd/system/default.target.wants/ | ||
RUN ln -s /usr/lib/systemd/system/sshd.service /usr/lib/systemd/system/default.target.wants/ | ||
RUN ln -s /usr/lib/systemd/system/populate-data-volume.service /usr/lib/systemd/system/default.target.wants/ | ||
COPY volume-data-list /etc/ | ||
|
||
ARG DEV_SSH_KEY | ||
ARG GO_VERSION | ||
ARG USER | ||
ARG USER_ID | ||
|
||
RUN useradd -m --uid=${USER_ID} ${USER} \ | ||
&& mkdir /home/${USER}/.ssh \ | ||
&& echo "$DEV_SSH_KEY" > /home/${USER}/.ssh/authorized_keys \ | ||
&& chmod 600 /home/${USER}/.ssh/authorized_keys \ | ||
&& echo 'export PATH=$PATH:/usr/local/go/bin' >> /home/${USER}/.bashrc \ | ||
&& chown -R ${USER}:${USER} /home/${USER} | ||
|
||
RUN install -o ${USER_ID} -g ${USER_ID} -m 0755 -d /app | ||
RUN wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz | ||
RUN tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz | ||
|
||
RUN echo "${USER} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-dev-user \ | ||
&& chmod 440 /etc/sudoers.d/90-dev-user | ||
|
||
ENV container docker | ||
VOLUME [ "/tmp", "/run", "/data" ] | ||
ENTRYPOINT /usr/sbin/init-data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
FROM freeipa/freeipa-server:centos-7 | ||
ARG IPA_ADMIN_PASS | ||
ARG IPA_DS_PASS | ||
COPY init-ipa-server-install-options ipa-precreate-hosts /usr/sbin/ | ||
COPY ipa-precreate-hosts.service /usr/lib/systemd/system/ | ||
RUN mkdir /usr/lib/systemd/system/container-ipa.target.wants \ | ||
&& ln -s /usr/lib/systemd/system/ipa-precreate-hosts.service /usr/lib/systemd/system/container-ipa.target.wants/ipa-precreate-hosts.service | ||
RUN ln -s /data /var/www/html/pub | ||
|
||
ENV IPA_ADMIN_PASS $IPA_ADMIN_PASS | ||
ENV IPA_DS_PASS $IPA_DS_PASS | ||
ENTRYPOINT [ "/usr/sbin/init-ipa-server-install-options" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#!/bin/bash | ||
|
||
# Copyright 2016--2017 Jan Pazdziora | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"). | ||
|
||
# Populates data in the image from the /data volume. Also | ||
# waits for the IPA server to be ready. | ||
|
||
set -e | ||
|
||
UNAME=$( uname -n ) | ||
if [ "$HOSTNAME" != "$UNAME" -a "$HOSTNAME" == "${UNAME%%.*}" ] ; then | ||
HOSTNAME="$UNAME" | ||
fi | ||
|
||
for i in /run/* /tmp/* ; do | ||
if [ -e "$i" -a "$i" != '/run/secrets' ] ; then | ||
rm -rf "$i" | ||
fi | ||
done | ||
|
||
if [ -f /data/volume-version ] ; then | ||
sed 's%^/%%' /etc/volume-data-list | while read f ; do [ -e /data/$f -o -L /data/$f ] && echo $f ; done | ( cd /data && xargs cp --parents -rp -t / ) | ||
fi | ||
|
||
DOMAIN=mokey.local | ||
IPA=ipa.$DOMAIN | ||
|
||
IPA_IP_FROM_DOCKER=$( host $IPA | awk '/has address (.+)/ { print $4; exit}' ) | ||
|
||
i=0 | ||
while ! curl -fs http://$IPA/ipa/config/ca.crt &> /dev/null ; do | ||
if [ "$(( i % 20 ))" -eq 0 ] ; then | ||
echo "Waiting for FreeIPA server (HTTP Server) ..." | ||
fi | ||
i=$(( i + 1 )) | ||
sleep 1 | ||
done | ||
i=0 | ||
while ! dig NS mokey.local &> /dev/null ; do | ||
if [ "$(( i % 20 ))" -eq 0 ] ; then | ||
echo "Waiting for FreeIPA server (DNS) ..." | ||
fi | ||
i=$(( i + 1 )) | ||
sleep 1 | ||
done | ||
|
||
echo "nameserver $IPA_IP_FROM_DOCKER" > /etc/resolv.conf | ||
echo "Pointing resolv.conf at $HOSTNAME to $IPA_IP_FROM_DOCKER" | ||
|
||
i=0 | ||
while true ; do | ||
IPA_IP_FROM_IPA=$( host $IPA | awk '/has address (.+)/ { print $4; exit}' ) | ||
if [ "$IPA_IP_FROM_DOCKER" == "$IPA_IP_FROM_IPA" ] ; then | ||
break | ||
fi | ||
if [ "$(( i % 20 ))" -eq 0 ] ; then | ||
echo "Waiting for FreeIPA server (its IP address in DNS) ..." | ||
fi | ||
i=$(( i + 1 )) | ||
sleep 1 | ||
done | ||
|
||
echo "FreeIPA server is ready." | ||
|
||
while ! ( set -x ; curl -o /etc/pki/ca-trust/source/anchors/ipa-ca.crt -fs http://$IPA/ipa/config/ca.crt ) ; do | ||
sleep 1 | ||
done | ||
( | ||
set -x | ||
update-ca-trust | ||
) | ||
|
||
( | ||
trap '' SIGHUP | ||
rm -rf /run/docker-console | ||
mkdir -p /run/docker-console | ||
(sleep infinity) & | ||
ln -s /proc/$!/fd /run/docker-console/ | ||
) | ||
|
||
exec /usr/sbin/init |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#!/bin/bash | ||
|
||
# Copyright 2016--2017 Jan Pazdziora | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"). | ||
|
||
# If the FreeIPA server does not contain ipa-server-install-options | ||
# and the server was not configured yet, produce some default | ||
# configuration for the developer setup. | ||
|
||
set -e | ||
|
||
cd / | ||
|
||
UNAME=$( uname -n ) | ||
if [ "$HOSTNAME" != "$UNAME" -a "$HOSTNAME" == "${UNAME%%.*}" ] ; then | ||
HOSTNAME="$UNAME" | ||
fi | ||
|
||
DATA=/data | ||
if ! [ -f /etc/ipa/ca.crt -a -f $DATA/ipa-server-install-options ] ; then | ||
echo "Configuring $HOSTNAME ..." | ||
echo $IPA_ADMIN_PASS > $DATA/admin-password | ||
echo $IPA_DS_PASS > $DATA/ds-master-password | ||
DOMAIN=${HOSTNAME#*.} | ||
REALM=${DOMAIN^^} | ||
cat > $DATA/ipa-server-install-options <<EOS | ||
--admin-password='$( cat $DATA/admin-password )' | ||
--ds-password='$( cat $DATA/ds-master-password )' | ||
--realm $REALM | ||
--setup-dns | ||
--no-forwarders | ||
--no-dnssec-validation | ||
--no-ntp | ||
-U | ||
EOS | ||
fi | ||
|
||
( | ||
trap '' SIGHUP | ||
rm -rf /run/docker-console | ||
mkdir -p /run/docker-console | ||
(sleep infinity) & | ||
ln -s /proc/$!/fd /run/docker-console/ | ||
) | ||
|
||
export SHOW_LOG=1 | ||
if [ -f /usr/sbin/init-data ] ; then | ||
exec /usr/sbin/init-data | ||
else | ||
exec /usr/local/sbin/init | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#!/bin/bash | ||
|
||
# Copyright 2016--2018 Jan Pazdziora | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"). | ||
|
||
# If the machine is not yet IPA-enrolled, fetch its OTP from the IPA | ||
# server and IPA-enroll the machine. In container with Apache HTTP | ||
# server, also get keytab for the HTTP/ service and SSL certificate. | ||
|
||
set -e | ||
|
||
exec >> /run/docker-console/fd/1 2>> /run/docker-console/fd/2 | ||
|
||
workaround_1708275 () { | ||
# Workaround 1708275 | ||
if ! grep -q dyndns_refresh_interval /etc/sssd/sssd.conf ; then | ||
sed -i '/^\[domain/adyndns_refresh_interval = 999999' /etc/sssd/sssd.conf | ||
fi | ||
} | ||
|
||
if [ -f /etc/ipa/default.conf ] ; then | ||
echo "$HOSTNAME is already IPA-enrolled." | ||
workaround_1708275 | ||
exit | ||
fi | ||
|
||
DOMAIN=mokey.local | ||
IPA=ipa.$DOMAIN | ||
|
||
i=0 | ||
while ! curl -fs https://$IPA/pub/$HOSTNAME-otp &> /dev/null ; do | ||
if [ "$(( i % 20 ))" -eq 0 ] ; then | ||
echo "Waiting for my host record and OTP ..." | ||
fi | ||
i=$(( i + 1 )) | ||
sleep 1 | ||
done | ||
|
||
( | ||
set -x | ||
curl -o /tmp/otp-password -fs https://$IPA/pub/$HOSTNAME-otp | ||
ipa-client-install --server $IPA --domain $DOMAIN --password $( cat /tmp/otp-password ) --enable-dns-updates --no-ntp --no-nisdomain --no-ssh --no-sshd --no-sudo --no-dns-sshfp --unattended | ||
) | ||
|
||
workaround_1708275 | ||
|
||
if id apache &> /dev/null ; then | ||
HTTP_CERT=/etc/pki/tls/certs/localhost.crt | ||
rm -f $HTTP_CERT | ||
|
||
( | ||
set -x | ||
|
||
kinit -k | ||
ipa-getkeytab -k /etc/http.keytab -s $IPA -p HTTP/$HOSTNAME | ||
chown apache /etc/http.keytab | ||
|
||
ipa-getcert request -k /etc/pki/tls/private/localhost.key -f $HTTP_CERT -N $HOSTNAME -K HTTP/$HOSTNAME -w | ||
chown apache $HTTP_CERT | ||
) | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[Unit] | ||
Description=IPA-enroll the machine to the FreeIPA server | ||
|
||
[Service] | ||
Type=oneshot | ||
ExecStart=/usr/sbin/ipa-client-enroll | ||
RemainAfterExit=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/bin/bash | ||
|
||
# Copyright 2016--2018 Jan Pazdziora | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"). | ||
|
||
# Prepare HBAC rules for services webapp and idp, and OTPs for IPA clients. | ||
|
||
set -e | ||
|
||
exec >> /var/log/ipa-server-run.log 2>&1 | ||
|
||
HOSTS="client.mokey.local" | ||
for i in $HOSTS ; do | ||
if ! [ -f /data/$i-otp ] ; then | ||
echo "Creating host record for $i" | ||
klist > /dev/null || kinit admin < /data/admin-password | ||
( | ||
set -x | ||
ipa host-find $i > /dev/null && ipa host-del $i | ||
ipa host-add --random $i --force --raw | awk '/randompassword:/ { print $2 }' > /data/$i-otp.1 | ||
ipa service-add --force HTTP/$i | ||
mv /data/$i-otp.1 /data/$i-otp | ||
) | ||
fi | ||
done | ||
|
||
kdestroy -A |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[Unit] | ||
Description=Create IPA client host records and OTPs, and HBAC rules | ||
After=ipa.service | ||
After=ipa-server-configure-first.service | ||
After=ipa-server-update-self-ip-address.service | ||
|
||
[Service] | ||
Type=oneshot | ||
ExecStart=/usr/sbin/ipa-precreate-hosts | ||
RemainAfterExit=true | ||
|
||
[Install] | ||
WantedBy=container-ipa.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/bin/bash | ||
|
||
# Copyright 2016 Jan Pazdziora | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"). | ||
|
||
# Upon the first run, populates the /data directory, to be used during | ||
# subsequent startups. | ||
|
||
set -e | ||
|
||
exec >> /run/docker-console/fd/1 2>> /run/docker-console/fd/2 | ||
|
||
if [ -f /data/volume-version ] ; then | ||
echo "The data volume is already populated on $HOSTNAME." | ||
exit | ||
fi | ||
|
||
cat /etc/volume-data-list | while read f ; do [ -e $f ] && echo $f ; done | ( set -x ; xargs cp --parents -rp -t /data ) | ||
set -x | ||
echo 0.1 > /data/volume-version |
Oops, something went wrong.