Skip to content

Commit

Permalink
Add NSBSD os support (#1333)
Browse files Browse the repository at this point in the history
* Add NSBSD support

* Import dns lib only when needed and handle import error

* Review from boumenot & jasonzio. Add deploy_ssh_pubkey, fix get_dhcp_pid & conf_sshd, raise an error if no dns.resolver is missing.
  • Loading branch information
remip2 authored and hglkrijger committed Sep 6, 2018
1 parent 527e863 commit 157d54a
Show file tree
Hide file tree
Showing 4 changed files with 284 additions and 1 deletion.
6 changes: 5 additions & 1 deletion azurelinuxagent/common/osutil/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from .bigip import BigIpOSUtil
from .gaia import GaiaOSUtil
from .iosxe import IosxeOSUtil
from .nsbsd import NSBSDOSUtil

from distutils.version import LooseVersion as Version

Expand Down Expand Up @@ -106,9 +107,12 @@ def get_osutil(distro_name=DISTRO_NAME,
elif distro_name == "gaia":
return GaiaOSUtil()

if distro_name == "iosxe":
elif distro_name == "iosxe":
return IosxeOSUtil()

elif distro_name == "nsbsd":
return NSBSDOSUtil()

else:
logger.warn("Unable to load distro implementation for {0}. Using "
"default distro implementation instead.",
Expand Down
159 changes: 159 additions & 0 deletions azurelinuxagent/common/osutil/nsbsd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#
# Copyright 2018 Stormshield
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.textutil as textutil
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.exception import OSUtilError
from azurelinuxagent.common.osutil.freebsd import FreeBSDOSUtil
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.conf as conf
import os
import time

class NSBSDOSUtil(FreeBSDOSUtil):

resolver = None

def __init__(self):
super(NSBSDOSUtil, self).__init__()

if self.resolver is None:
# NSBSD doesn't have a system resolver, configure a python one

try:
import dns.resolver
except ImportError:
raise OSUtilError("Python DNS resolver not available. Cannot proceed!")

self.resolver = dns.resolver.Resolver()
servers = []
cmd = "getconf /usr/Firewall/ConfigFiles/dns Servers | tail -n +2"
ret, output = shellutil.run_get_output(cmd)
for server in output.split("\n"):
if server == '':
break
server = server[:-1] # remove last '='
cmd = "grep '{}' /etc/hosts".format(server) + " | awk '{print $1}'"
ret, ip = shellutil.run_get_output(cmd)
servers.append(ip)
self.resolver.nameservers = servers
dns.resolver.override_system_resolver(self.resolver)

def set_hostname(self, hostname):
shellutil.run("/usr/Firewall/sbin/setconf /usr/Firewall/System/global SystemName {0}".format(hostname))
shellutil.run("/usr/Firewall/sbin/enlog")
shellutil.run("/usr/Firewall/sbin/enproxy -u")
shellutil.run("/usr/Firewall/sbin/ensl -u")
shellutil.run("/usr/Firewall/sbin/ennetwork -f")

def restart_ssh_service(self):
return shellutil.run('/usr/Firewall/sbin/enservice', chk_err=False)

def conf_sshd(self, disable_password):
option = "0" if disable_password else "1"

shellutil.run('setconf /usr/Firewall/ConfigFiles/system SSH State 1',
chk_err=False)
shellutil.run('setconf /usr/Firewall/ConfigFiles/system SSH Password {}'.format(option),
chk_err=False)
shellutil.run('enservice', chk_err=False)

logger.info("{0} SSH password-based authentication methods."
.format("Disabled" if disable_password else "Enabled"))

def useradd(self, username, expiration=None):
"""
Create user account with 'username'
"""
logger.warn("User creation disabled")
return

def del_account(self, username):
logger.warn("User deletion disabled")

def conf_sudoer(self, username, nopasswd=False, remove=False):
logger.warn("Sudo is not enabled")

def chpasswd(self, username, password, crypt_id=6, salt_len=10):
cmd = "/usr/Firewall/sbin/fwpasswd -p {0}".format(password)
ret, output = shellutil.run_get_output(cmd, log_cmd=False)
if ret != 0:
raise OSUtilError(("Failed to set password for admin: {0}"
"").format(output))

# password set, activate webadmin and ssh access
shellutil.run('setconf /usr/Firewall/ConfigFiles/webadmin ACL any && ensl',
chk_err=False)

def deploy_ssh_pubkey(self, username, pubkey):
"""
Deploy authorized_key
"""
path, thumbprint, value = pubkey

#overide parameters
super(NSBSDOSUtil, self).deploy_ssh_pubkey('admin',
["/usr/Firewall/.ssh/authorized_keys", thumbprint, value])

def del_root_password(self):
logger.warn("Root password deletion disabled")

def start_dhcp_service(self):
shellutil.run("/usr/Firewall/sbin/nstart dhclient", chk_err=False)

def stop_dhcp_service(self):
shellutil.run("/usr/Firewall/sbin/nstop dhclient", chk_err=False)

def get_dhcp_pid(self):
ret = None
pidfile = "/var/run/dhclient.pid"

if os.path.isfile(pidfile):
ret = fileutil.read_file(pidfile, encoding='ascii')
return ret

def eject_dvd(self, chk_err=True):
pass

def restart_if(self, ifname):
# Restart dhclient only to publish hostname
shellutil.run("ennetwork", chk_err=False)

def set_dhcp_hostname(self, hostname):
#already done by the dhcp client
pass

def get_firewall_dropped_packets(self, dst_ip=None):
# disable iptables methods
return 0

def get_firewall_will_wait(self):
# disable iptables methods
return ""

def _delete_rule(self, rule):
# disable iptables methods
return

def remove_firewall(self, dst_ip=None, uid=None):
# disable iptables methods
return True

def enable_firewall(self, dst_ip=None, uid=None):
# disable iptables methods
return True
3 changes: 3 additions & 0 deletions azurelinuxagent/common/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ def get_distro():
osinfo = ['openbsd', release, '', 'openbsd']
elif 'Linux' in platform.system():
osinfo = get_linux_distribution(0, 'alpine')
elif 'NS-BSD' in platform.system():
release = re.sub('\-.*\Z', '', ustr(platform.release()))
osinfo = ['nsbsd', release, '', 'nsbsd']
else:
try:
# dist() removed in Python 3.7
Expand Down
117 changes: 117 additions & 0 deletions config/nsbsd/waagent.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#
# Microsoft Azure Linux Agent Configuration
#

# Enable instance creation
Provisioning.Enabled=y

# Rely on cloud-init to provision
Provisioning.UseCloudInit=n

# Password authentication for root account will be unavailable.
Provisioning.DeleteRootPassword=n

# Generate fresh host key pair.
Provisioning.RegenerateSshHostKeyPair=n

# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto".
# The "auto" option is supported on OpenSSH 5.9 (2011) and later.
Provisioning.SshHostKeyPairType=rsa

# Monitor host name changes and publish changes via DHCP requests.
Provisioning.MonitorHostName=y

# Decode CustomData from Base64.
Provisioning.DecodeCustomData=n

# Execute CustomData after provisioning.
Provisioning.ExecuteCustomData=n

# Algorithm used by crypt when generating password hash.
#Provisioning.PasswordCryptId=6

# Length of random salt used when generating password hash.
#Provisioning.PasswordCryptSaltLength=10

# Format if unformatted. If 'n', resource disk will not be mounted.
ResourceDisk.Format=n

# File system on the resource disk
# Typically ext3 or ext4. FreeBSD images should use 'ufs' here.
ResourceDisk.Filesystem=ufs

# Mount point for the resource disk
ResourceDisk.MountPoint=/mnt/resource

# Create and use swapfile on resource disk.
ResourceDisk.EnableSwap=n

# Size of the swapfile.
ResourceDisk.SwapSizeMB=0

# Comma-seperated list of mount options. See man(8) for valid options.
ResourceDisk.MountOptions=None

# Enable verbose logging (y|n) TODO set n
Logs.Verbose=n

# Is FIPS enabled
OS.EnableFIPS=n

# Root device timeout in seconds.
OS.RootDeviceScsiTimeout=300

# If "None", the system default version is used.
OS.OpensslPath=None

# Set the path to SSH keys and configuration files
OS.SshDir=/etc/ssh

OS.PasswordPath=/etc/master.passwd

OS.SudoersDir=/usr/local/etc/sudoers.d

# If set, agent will use proxy server to access internet
#HttpProxy.Host=None
#HttpProxy.Port=None

# Detect Scvmm environment, default is n
# DetectScvmmEnv=n

#
Lib.Dir=/usr/Firewall/var/waagent

#
# DVD.MountPoint=/mnt/cdrom/secure

#
# Pid.File=/var/run/waagent.pid

#
Extension.LogDir=/log/azure

#
# Home.Dir=/home

# Enable RDMA management and set up, should only be used in HPC images
# OS.EnableRDMA=y

# Enable or disable goal state processing auto-update, default is enabled
AutoUpdate.Enabled=n

# Determine the update family, this should not be changed
# AutoUpdate.GAFamily=Prod

# Determine if the overprovisioning feature is enabled. If yes, hold extension
# handling until inVMArtifactsProfile.OnHold is false.
# Default is disabled
# EnableOverProvisioning=n

# Allow fallback to HTTP if HTTPS is unavailable
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
# OS.AllowHTTP=n

# Add firewall rules to protect access to Azure host node services
# Note:
# - The default is false to protect the state of existing VMs
OS.EnableFirewall=n

0 comments on commit 157d54a

Please sign in to comment.