Skip to content

Commit

Permalink
Merge pull request #29 from riddhi-ibm/enable_nfs_over_tls
Browse files Browse the repository at this point in the history
Experimental testing NFS using TLS for specific OS versions
  • Loading branch information
DreamAmbitious authored Sep 27, 2024
2 parents 2b6f4cb + 2ccc395 commit bc18c97
Show file tree
Hide file tree
Showing 6 changed files with 304 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
-----BEGIN CERTIFICATE-----
MIIFljCCBH6gAwIBAgIUNX3isp/i5hTNhwd/aVz1gXz2aqUwDQYJKoZIhvcNAQEL
BQAwbDELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRIwEAYDVQQKEwlJQk0g
Q2xvdWQxFDASBgNVBAsTC1ZQQyBTdG9yYWdlMSMwIQYDVQQDExpjbG91ZC5pYm0u
dnBjLnN0b3JhZ2UuZmlsZTAeFw0yNDA5MDYxMTE2NDZaFw0zNDA5MDQxMTE3MTVa
MGwxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIEwVUZXhhczESMBAGA1UEChMJSUJNIENs
b3VkMRQwEgYDVQQLEwtWUEMgU3RvcmFnZTEjMCEGA1UEAxMaY2xvdWQuaWJtLnZw
Yy5zdG9yYWdlLmZpbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb
yA91DDfESBnG06C5velPGty2ZR2ookqWom/5ZG6694bAo5y7D/sSsX4H7VR2DBvT
yDrfWq9TgvhcNbYPCPjX+P5FMGd0FWOm7vxv+HvLQNjsV8nsEE9qAovxigV5zghX
WzE0C3DpGCPFZT3XMmp6hKFPzdNtAltESruIGcyp68my7WZ+D4u1CC0P4zJK0+PF
/K7r3Yetbj8odLVjqTKVId4JXNfsgMzmqsqoHWIkiEcH+IHPbScFF1d0ld7rS2Yp
iRhX0mECSUceOen64UuVCZDeodY6QZkf7ZALo+Z1o2hz8KElO+c8ix17LmgsklMX
5l3lg10IhhqObfk0uFY9AgMBAAGjggIuMIICKjAOBgNVHQ8BAf8EBAMCAQYwDwYD
VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUtTOqRMaVh5CyiGb0Rrhn4gQxy6QwHwYD
VR0jBBgwFoAUtTOqRMaVh5CyiGb0Rrhn4gQxy6QwggGeBggrBgEFBQcBAQSCAZAw
ggGMMIG/BggrBgEFBQcwAoaBsmh0dHBzOi8vZDA5MzcyNDQtNGI0MC00NDRlLThj
ZjItOWRkZWE3Yzk3Y2M5LmV1LWdiLnNlY3JldHMtbWFuYWdlci50ZXN0LmFwcGRv
bWFpbi5jbG91ZC92MS9pYm1jbG91ZC9wcml2YXRlX2NlcnQvY29uZmlnL2NlcnRp
ZmljYXRlX2F1dGhvcml0aWVzL3ZwYy1maWxlLW5mcy10bHMtcm9vdC1zdGFnZS9j
YS9wZW0wgccGCCsGAQUFBzAChoG6aHR0cHM6Ly9kMDkzNzI0NC00YjQwLTQ0NGUt
OGNmMi05ZGRlYTdjOTdjYzkucHJpdmF0ZS5ldS1nYi5zZWNyZXRzLW1hbmFnZXIu
dGVzdC5hcHBkb21haW4uY2xvdWQvdjEvaWJtY2xvdWQvcHJpdmF0ZV9jZXJ0L2Nv
bmZpZy9jZXJ0aWZpY2F0ZV9hdXRob3JpdGllcy92cGMtZmlsZS1uZnMtdGxzLXJv
b3Qtc3RhZ2UvY2EvcGVtMCUGA1UdEQQeMByCGmNsb3VkLmlibS52cGMuc3RvcmFn
ZS5maWxlMA0GCSqGSIb3DQEBCwUAA4IBAQCLyuhe0fld7VcCfmHdmyx9HZ8o6a7o
e1vhHHLU9x7NZftMp8EHv76hxDJg6tVChnrRT4Y6JeYEbm1N2F099/BOlgoqW3na
0ssg+sI4ybGaGPS0XWX8CcEIPFsGqUdOL7bPLiQjGIF/sF/iq9lWSSFbiaX7niCU
mklnvADanSUnMoTZhy8kFTl62y7RtmTmYsmWbVVEYJFOgsJ//QcLJnAVNtZXitk4
jjk2Tlo593IwowdyhpYQbjf8B1pIMUNsv/mU7E5kf4X+xWst9VthN1W3Upfzizxb
Ney27PkE4xq0Kb6qYNivTXfRCoJrLnmDIVHza9UUKs2EUDc6aZO6uYlK
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFVzCCBD+gAwIBAgIUQ2uTN6v6K8T9JXpJAESgr3O6WsAwDQYJKoZIhvcNAQEL
BQAwbDELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMRIwEAYDVQQKEwlJQk0g
Q2xvdWQxFDASBgNVBAsTC1ZQQyBTdG9yYWdlMSMwIQYDVQQDExpjbG91ZC5pYm0u
dnBjLnN0b3JhZ2UuZmlsZTAeFw0yNDA5MDYxMTI0MzRaFw0yOTA5MDUxMTI1MDRa
MCkxJzAlBgNVBAMTHmNsb3VkLmlibS52cGMuc3RvcmFnZS5maWxlLmludDCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKEVY8U4U9NWUVylIIkmsw4iVXFo
nilgXckKCVaWpSWIYb94Y2R9+kv8hBBqLZGdBIWPP8YzrRE5AtX5Ss1eAq94x36U
2OwBSsegA5oBtPsfoF2snqpVPbe9c9Liv81cOHnZmF0XtPiYRQ6vm+lsEHvQ7M9p
aWhffIYGu9adDMYFI4/0XnA/mapRsjR5RutK8HjBT+lh1TmS2gIXgUbW0h4co/Tv
7S39a6uE6Xa58NZaOb2KHWOldeS9+BbeboHsy0wKQJmczN0esCwk+l5p2JDQgvF3
LMR3h0iGR87VqaadJ1TOjdFgU2gav+34ciJ5CFO6lZ2l6EDN8jbz1+Xu9wcCAwEA
AaOCAjIwggIuMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
DgQWBBR9m40OA2pKBJU351tp2sj0qT0FHjAfBgNVHSMEGDAWgBS1M6pExpWHkLKI
ZvRGuGfiBDHLpDCCAZ4GCCsGAQUFBwEBBIIBkDCCAYwwgb8GCCsGAQUFBzAChoGy
aHR0cHM6Ly9kMDkzNzI0NC00YjQwLTQ0NGUtOGNmMi05ZGRlYTdjOTdjYzkuZXUt
Z2Iuc2VjcmV0cy1tYW5hZ2VyLnRlc3QuYXBwZG9tYWluLmNsb3VkL3YxL2libWNs
b3VkL3ByaXZhdGVfY2VydC9jb25maWcvY2VydGlmaWNhdGVfYXV0aG9yaXRpZXMv
dnBjLWZpbGUtbmZzLXRscy1yb290LXN0YWdlL2NhL3BlbTCBxwYIKwYBBQUHMAKG
gbpodHRwczovL2QwOTM3MjQ0LTRiNDAtNDQ0ZS04Y2YyLTlkZGVhN2M5N2NjOS5w
cml2YXRlLmV1LWdiLnNlY3JldHMtbWFuYWdlci50ZXN0LmFwcGRvbWFpbi5jbG91
ZC92MS9pYm1jbG91ZC9wcml2YXRlX2NlcnQvY29uZmlnL2NlcnRpZmljYXRlX2F1
dGhvcml0aWVzL3ZwYy1maWxlLW5mcy10bHMtcm9vdC1zdGFnZS9jYS9wZW0wKQYD
VR0RBCIwIIIeY2xvdWQuaWJtLnZwYy5zdG9yYWdlLmZpbGUuaW50MA0GCSqGSIb3
DQEBCwUAA4IBAQCfIvILMffJS+Myu+xoaeJiSXZZ1Q7lOME5ghKwmCvsTMkDnBzJ
gwDVMDqfLMWbZRglgo4972LRyYIUZkJ4Y9cuzA/qT4le1y3AUhSExl5qt1GFBC05
/ELrxp54dTgzJ0cnzpDfuxjTWaVrp5DkZKuYW3tboE3PkefL9W0y9xqFyG2UvlSg
4s2yRyK1/VoQ5bQcUD20Ck99qInOVASF7lOv14+KRaeFe7Dq0NnxWAPGYh9mkfp1
KgFRxg/9Oy/phMbWRYtrK3dD9DPKBwILSZ57Wmewjdpfy0ghZ/+4dgH24Sx29qVY
rRm4yaH7Kvw0/MF9soEQotLpUQ4lDKrSh8aR
-----END CERTIFICATE-----
67 changes: 66 additions & 1 deletion mount-helper/install/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# This project is licensed under the MIT License, see LICENSE file in the root directory.

INSTALL_ARG="$1"
INSTALL_MOUNT_OPTION_ARG="$2"

APP_NAME="IBM Mount Share Helper"
SCRIPT_NAME="mount.ibmshare"
Expand Down Expand Up @@ -62,6 +63,14 @@ check_linux_version () {
log "Linux($NAME) Version($VERSION) distro"
}

check_tls_supported_linux_verion() {
if { is_linux LINUX_UBUNTU && [[ "$VERSION" == 24.04 ]]; } || { is_linux LINUX_RED_HAT && [[ "$VERSION" == 9.4 ]]; } || { is_linux LINUX_ROCKY && [[ "$VERSION" == 9.4 ]]; }; then
log "Linux($NAME) Version($VERSION) supports TLS"
else
exit_err "TLS is not supported on this OS version"
fi
}

is_linux () {
eval 'ARRAY=( "${'"$1"'[@]}" )'
local _NAME=${ARRAY[0]}
Expand Down Expand Up @@ -388,22 +397,75 @@ disable_metadata () {
sed -i 's/USE_METADATA_SERVICE = True/USE_METADATA_SERVICE = False/' $SBIN_SCRIPT
}

install_tls_certificates() {
CERT_PATH="$1"
if is_linux LINUX_UBUNTU && [[ "$VERSION" == 24.04 ]]; then
TLS_CERT_PATH="/usr/local/share/ca-certificates"
cp "$CERT_PATH"/* "$TLS_CERT_PATH/"
if [ $? -eq 0 ]; then
echo "CA certificates for TLS copied successfully to usr/local/share/ca-certificates."
else
exit_err "Error: Failed to copy ca-certificates for TLS copied ."
fi
echo "Updating CA certificates..."
sudo update-ca-certificates
if [ $? -eq 0 ]; then
echo "CA certificates updated successfully."
else
exit_err "Error: Failed to update CA certificates."
fi
fi
if { is_linux LINUX_RED_HAT && [[ "$VERSION" == 9.4 ]]; } || { is_linux LINUX_ROCKY && [[ "$VERSION" == 9.4 ]]; }; then
TLS_CERT_PATH="/etc/pki/ca-trust/source/anchors"
for CERT in "$CERT_PATH"/*.crt; do
if [ -f "$CERT" ]; then
CERT_NAME=$(basename "$CERT" .crt)
sudo cp "$CERT" "$TLS_CERT_PATH/$CERT_NAME.pem"
fi
done
if [ $? -eq 0 ]; then
echo "CA certificates for TLS copied and renamed successfully to $TLS_CERT_PATH."
else
exit_err "Error: Failed to copy CA certificates."
fi
echo "Updating CA certificates..."
sudo update-ca-trust anchors
if [ $? -eq 0 ]; then
echo "CA certificates updated successfully."
else
exit_err "Error: Failed to update CA certificates."
fi
fi
}
init_mount_helper () {
if [[ "$INSTALL_ARG" == "region="* ]]; then
log "Updating config file: ./share.conf"
sed -i "s/region=.*/$INSTALL_ARG/" ./share.conf
INSTALL_ARG=""
fi
if [[ "$INSTALL_MOUNT_OPTION_ARG" == "stage" ]]; then
exit_err "incorrect command, pass stage as first arg."
fi
if [[ "$INSTALL_ARG" == "--tls" || "$INSTALL_MOUNT_OPTION_ARG" == "--tls" ]]; then
check_tls_supported_linux_verion
fi
if [[ "$INSTALL_ARG" == "stage" || "$INSTALL_ARG" == "--update-stage" ]]; then
CERT_PATH="./dev_certs/metadata"
log "Installing certs for stage environment..."
$SBIN_SCRIPT -INSTALL_ROOT_CERT $CERT_PATH
check_result "Problem installing ssl certs"
if [[ "$INSTALL_MOUNT_OPTION_ARG" == "--tls" ]]; then
install_tls_certificates $CERT_PATH
fi
exit_ok "Install completed ok"
fi
if [[ "$INSTALL_ARG" == "" || "$INSTALL_ARG" == "--update" ]]; then
if [[ "$INSTALL_ARG" == "" || "$INSTALL_ARG" == "--update" || "$INSTALL_ARG" == "--tls" ]]; then
if [[ "$INSTALL_ARG" == "--tls" ]]; then
INSTALL_MOUNT_OPTION_ARG="--tls"
fi
INSTALL_ARG="metadata"
fi

log "Installing certs for: $INSTALL_ARG"
CERT_PATH="./certs/$INSTALL_ARG"
if [ ! -d $CERT_PATH ]; then
Expand All @@ -414,6 +476,9 @@ init_mount_helper () {
fi
$SBIN_SCRIPT -INSTALL_ROOT_CERT $CERT_PATH
check_result "Problem installing ssl certs"
if [[ "$INSTALL_MOUNT_OPTION_ARG" == "--tls" ]]; then
install_tls_certificates $CERT_PATH
fi
exit_ok "Install completed ok"
}

Expand Down
57 changes: 57 additions & 0 deletions mount-helper/install/tls.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash
#
# Copyright (c) IBM Corp. 2024. All Rights Reserved.
# Project name: VPC File Storage Mount Helper
# This project is licensed under the MIT License, see LICENSE file in the root directory.

FILE_PATH="/etc/hosts"
ip_address=$1

# Function to validate IP address format
is_valid_ip() {
local ip=$1
local valid_ip_regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$"

if [[ $ip =~ $valid_ip_regex ]]; then
IFS='.' read -r -a octets <<< "$ip"
for octet in "${octets[@]}"; do
if (( octet < 0 || octet > 255 )); then
echo "Invalid IP address format."
return 1 # Invalid octet
fi
done

# Check for special IP addresses
if [[ $ip == "0.0.0.0" ]] ||
[[ $ip == "255.255.255.255" ]]; then
echo "Special IPs not allowed."
return 1 # Special IP addresses are considered invalid for this context
fi

return 0 # Valid public IP address
else
return 1 # Invalid format
fi
}

# Function to validate hostname extension
is_valid_host_extension() {
local hostname=$1
if [[ $hostname == *.ibm.vpc.file.storage ]]; then
return 0
else
echo "The hostname does NOT have the correct extension."
return 1
fi
}

# Main logic
if is_valid_ip "$ip_address" || is_valid_host_extension "$ip_address"; then
if grep -q "$ip_address" "$FILE_PATH"; then
grep "$ip_address" "$FILE_PATH" | awk '{print $2}'
else
echo "$ip_address ibmshare_${ip_address//./_}.ibm.vpc.file.storage" | tee -a "$FILE_PATH"
fi
else
exit 1
fi
79 changes: 76 additions & 3 deletions mount-helper/src/args_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
INSTALL_ROOT_CERT = "-INSTALL_ROOT_CERT"
SECURE_OPTION = 'secure'
SECURE_ARG = 'true'
MOUNT_OPTION_TLS = 'tls'
TLS_OPTION = 'xprtsec=tls'
MOUNT_OPTION_IPSEC= 'ipsec'
SBIN_SCRIPT = "/sbin/mount.ibmshare"
TEARDOWN_APP = "-TEARDOWN_APP"
TLS_ENABLED_OS= [ "Ubuntu 24.04","Red Hat Enterprise Linux 9.4","Rocky Linux 9.4" ]


class AppRunType(object):
Expand Down Expand Up @@ -55,6 +59,7 @@ def __init__(self):
self.mount_source = None
self.options = None
self.is_secure = False
self.is_tls=False

def parse(self):
is_error = False
Expand All @@ -79,7 +84,7 @@ def parse_error(errmsg):
return self.LogError('Provide the mount source as <nfs_host>:<path>(' + self.mount_source + ').')
if len(self.mount_point) <= 0:
return self.LogError("Provide the mount point to mount on local host.")
self.options, self.is_secure = self.get_mount_options(args.o)
self.options, self.is_secure, self.is_tls = self.get_mount_options(args.o)
return True

@staticmethod
Expand Down Expand Up @@ -129,19 +134,42 @@ def set_logging_level():
# Method to return all -o option list of mount command.
def get_mount_options(self, opts_in):
is_secure = False
is_tls = False
is_ipsec=False
options = opts_in.split(',')
o_options = []
for option in options:
if not SECURE_OPTION in option.lower():
o_options.append(option)
if MOUNT_OPTION_TLS == option.lower():
if self.tls_on_version()==True:
is_tls = True
else:
sys.exit(0)
elif MOUNT_OPTION_IPSEC == option.lower():
is_ipsec=True
is_secure = True
else:
o_options.append(option)
elif SECURE_ARG in option.lower().split('='):
is_secure = True

return ','.join(o_options), is_secure
if is_tls and is_ipsec:
self.LogError("Choose either Ipsec or tls mount")
sys.exit(0)
elif is_tls:
o_options.append(TLS_OPTION)
if is_secure:
#dont generate certs
print("non eit mount")
return ','.join(o_options), is_secure,is_tls

# Method to contruct mount command to run finally.
def get_mount_cmd_line(self):
assert len(self.mount_source) > 0
if self.is_tls:
tls_mount_source=self.get_tls_mount_source()
if tls_mount_source != "":
self.mount_source=tls_mount_source
cmd = [MOUNT, MOUNT_T_OPTION, NFS_VERSION, MOUNT_O_OPTION, ','.join(
[ESSENTIAL_OPTIONS, self.options]), self.mount_source, self.mount_point]

Expand All @@ -150,3 +178,48 @@ def get_mount_cmd_line(self):
cmd.append(MOUNT_VERBOSE_FLAG)

return cmd
def tls_on_version(self):
system_ctl = SystemCtl(self)
required_packages_for_tls=['ktls-utils','ca-certificates']
if system_ctl.check_tls_enabled_os(TLS_ENABLED_OS) and system_ctl.is_kernel_version_6_or_higher():
for package in required_packages_for_tls:
if system_ctl.tls_package_installed(package):
self.LogDebug(package+" package is installed on the system")
else:
self.LogError("TLS is not supported , package is not installed on the system: "+package)
return False
return True
else:
self.LogError("TLS is not supported on current version, make sure kernel version is 6.x ")
return False
def get_tls_mount_source(self):
self.ip_address, self.mount_path = NfsMount.extract_source(self.mount_source)
file_path = '/etc/hosts'
self.check_and_add_ip_to_hosts()
if self.FileExists(file_path):
with open(file_path, 'r') as content:
for line in content:
tls_mount_source = line.split()
if len(tls_mount_source) >= 2:
ip_address = tls_mount_source[0]
value = tls_mount_source[1]
if ip_address == self.ip_address:
self.LogInfo("Using corresponding mount address to honour tls connection " +value)
self.mount_source=value+":"+self.mount_path
return self.mount_source

def check_and_add_ip_to_hosts(self):
file_path = '/etc/hosts'
with open(file_path, 'r') as content:
lines = content.readlines()
ip_exists = any(line.startswith(self.ip_address) for line in lines)
if not ip_exists:
try:
subprocess.run(['./tls.sh',self.ip_address], check=True)
self.LogInfo("Added ip address in /etc/hosts.")
except subprocess.CalledProcessError as e:
sys.exit(0)




Loading

0 comments on commit bc18c97

Please sign in to comment.