Author Archives: Fitzdsl

Comment utiliser le nouveau virsh provider de Foreman 1.4

Ce matin j’ai décidé de tester une nouvelle fonctionalité de Foreman 1.4 : le nouveau DHCP, DNS et TFTP provider : virsh.
Virsh provider permet de manager via la Libvirt les réseaux virtuels (via dnsmasq) pour du test ou du dévelopement en local. Cela permet d’avoir un workflow complet de provisioning sans avoir à installer bind, tftpd et dhcpd.

Ce post est largement inspiré de la documentation de Foreman 1.4.

Configuration de la Libvirt

La première chose à faire est de configurer un réseau persistent à la libvirt.
Créez un fichier nommé net-defintion.xml. Vous pouvez bien sur changer le nom du réseau, les ranges d’IP, le nom du domaine, etc ..

$ cat net-defintion.xml
<network>
<name>default</name>
<uuid>16b7b280-7462-428c-a65c-5753b84c7545</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:b2:fa:27'/>
<domain name='fitzdsl.local'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<tftp root='/tftp'/>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
<bootp file='pxelinux.0'/>
</dhcp>
</ip>
</network>

Vous devez ensuite créer et démarrer le réseau par la libvirt:

# virsh net-define --file net-definition.xml
# virsh net-start default

Ensuite nous devons configurer le répertoire qui va servir les fichiers TFTP. Les commandes ci-dessous viennent tout droit de la documentation de Foreman pour Fedora :

mkdir -p /var/tftproot/{boot,pxelinux.cfg}
yum -y install syslinux
cp /usr/share/syslinux/{pxelinux.0,menu.c32,chain.c32} /var/tftproot
chgrp -R nobody /var/tftproot
find /var/tftproot/ -type d | xargs chmod g+s

Configuration du smart-Proxy

Vous devez avoir un smart-proxy qui tourne en local sur votre machine. Celui-ci va prendre en charge TFTP, DNS and DHCP.
Il faut maintenant configurer celui pour utiliser le nouveau provider :

:tftp: true
:tftproot: /var/tftproot
:tftp_servername: 192.168.122.1
:dns: true
:dns_provider: virsh
:dhcp: true
:dhcp_vendor: virsh
:virsh_network: default

Vérifiez que votre smart-proxy a les droits sudo suivants:

Defaults !requiretty
foreman-proxy ALL=/usr/bin/virsh

Configuration de Foreman

Vous devez d’abord créer le smart-proxy (ou raffraichir ses features si il existait déjà):

Dans Infrastructure:
New proxy : http://localhost:8443

Vous devez ensuite créer un nouveau domaine et sous-réseau:

  • Créez un nouveau domaine et nommez le de manière à ce qu’il match le « domain name » du fichier net-defintion.xml.
  • Créez un nouveau sous-réseau ayant les mêmes valeurs que le fichier net-definition.xml

Dans mon cas:

Name: Home
Network address: 192.168.122.0
Netmask: 255.255.255.0
Start IP Range: 192.168.122.2
Stop IP Range: 192.168.122.255
  • Dans l’onglet « Domains », cochez le domaine que vous venez de créer.
  • Dans l’onglet « Proxies », selectionnez le proxy local pour DHCP, TFTP and DNS.

Créer une nouvelle VM

Lorsque vous allez créer une nouvelle VM, prennez soin de sélectionner dans l’onglet « Virtual Machine »:

  • Network Type => Virtual (NAT)
  • Network => « default »

Vous savez maintenant créer un environement complet de provisioning avec Foreman. La seule fonctionalité manquante est le que PTR record n’est pas créé.

Un grand merci à Lukas (@lzap) qui à implémenté cette super fonctionnalité !

Share

Utiliser PKGNG sous FreeBSD avec Puppet

Voici la procédure que j’ai appliquée pour utiliser le nouveau package manager de FreeBSD.
Cette méthode a été testée sur une Jail en FreeBSD 8.3 avec puppet 3.2.

Mettre en place pkgng

La procédure officielle se trouve içi.

Installation de pkgng :

# portsnap fetch update
# portmaster -dB ports-mgmt/pkg

Conversion du la base de package au nouveau format de pkgng. Attention ! Comme indiqué dans la documentation, cette étape est irréversible et ne vous permettra plus d’utiliser pkg_add comme package provider.

# pkg2ng

Pour indiquer l’utilisation de pkgng, il faut modifier make.conf :

# echo "WITH_PKGNG=yes" >> /etc/make.conf

Définir le nouveau repository pour pkgng :

# mkdir -p /usr/local/etc/pkg/repos
# cat << 'EOF' > /usr/local/etc/pkg/repos/FreeBSD.conf
FreeBSD: {
  url: "http://pkg.FreeBSD.org/${ABI}/latest",
  mirror_type: "srv",
  enabled: "yes"
}
EOF
# pkg update

Votre pkgng devrait être prêt à utilisation :

# pkg update
# pkg install sl # (mon paquet de test de prédilection !)
# sl

pkg peut afficher un message d’erreur (seulement un warning) :

pkg: Invalid configuration format, ignoring the configuration file

C’est un bug connu lié au fait que le fichier /usr/local/etc/pkg.conf est vide.
La version 1.2 devrait fixer ce problème.

Ajouter le provider pkgng à Puppet

Un nouveau provider de package pour Puppet existe déjà.
Vous pouvez trouver le repo github ici.

Pour installer le module, vous pouvez cloner le repo ou utiliser puppet module install :

# cd ~puppet/modules/
# puppet module install xaque208/pkgng

Je n’ai personnellement pas utilisé le manifest du module ( init.pp et params.pp), j’utilise seulement le nouveau provider contenu dans le dossier lib.

Il faut maintenant changer le provider par de package par défault dans Puppet. Je l’ai fait dans site.pp :

if $::operatingsystem == 'FreeBSD' {
        Package {
                provider => $::operatingsystem ? {
                        FreeBSD => pkgng
                }
        }
}

Vous pouvez maintenant définir des ressources packages dans puppet qui seront managées par pkgng :

package {
	'sl':
		#ensure => installed;
		ensure => absent;
}
Share

Sortie de Foreman 1.3

Quoi de neuf dans cette nouvelle version ?

Foreman 1.3 vient d’être releasé par la Core Team, regardons les nouveautés qu’apporte cette nouvelle version :

  1. L’installeur est maintenant basé sur le projet Kafo : je ne l’ai personnellement pas testé puisque j’installe toujours Foreman à partir des sources en checkoutant avec git
  2. Le projet hammer qui est la CLI de Foreman avance ! C’est une bonne chose puisque ca manquait au début du projet. Les développeurs préviennent cependant que les fonctionnalités sont encore limitées pour le moment. Affaire à suivre donc.
  3. Au niveau des Compute Resources, le très attendu support des VPC (Virtual Private Cloud) d’Amazon EC2 arrive enfin. D’autre part, le support de GCE (Google Compute Engine) arrive en version béta. Il est pour l’instant limité, ne supportant pas par exemple la création d’instances nécessitant des disques persistants
  4. Le support de SPICE est enfin disponible avec les Compute Resources de type Libvirt
  5. Foreman permet enfin de transformer une VM vue par Foreman comme un Host BareMetal en … VM !
  6. L’API évolue toujours avec l’arrivée de la v2 qui est toujours ‘expérimentale’. Les nouveautés sont : le support de REMOTE_USER, des smart classes, la gestion des interfaces réseaux, le power management et les boot devices. L’API v1 reste toujours donc par défaut.
  7. Il existe maintenant une commande foreman-rake qui est un wrapper aux différentes commandes rake

Les traductions sont améliorées et Foreman est maintenant traduit dans 6 langues. N’hésitez pas à participer sur le Transifex de Foreman.

Notes avant de migrer

La structure des formats de Reports et d’upload de Facts à changé avec la suppression de Puppet comme dépendance de Foreman Core.

  • Il faut donc impérativement changer votre script d’external node (/etc/puppet/node.rb) sur votre puppet master et utiliser le nouveau que vous pouvez trouver ici.
  • Il faut aussi changer votre script d’upload de report sur votre puppet master et utiliser celui-ci

Supprimer Puppet de Foreman Core est une très bonne chose. Cela va permettre dorénavant l’ajout d’autre Configuration Management System tel que Chef ou CFEngine. Il est à noter qu’un projet de support de Chef à déjà commencé, vous pouvez le trouver ici

La release note originale et le changelog sont ici.
A vos migrations !

Share

Nouveau webservice pour gérer les downtimes de supervision avec Livestatus

Suite à mon précédent article sur la supervision distribuée, j’ai du mettre à jour ma méthode pour gérer les downtimes de Nagios que j’avais expliqué dans cet article.
J’ai donc complètement réécris ce webservice en python en me reposant sur Livestatus. Les source du script sont sur Github.
Ce script supporte donc d’avoir plusieurs démons Livestatus sur différents serveurs.
L’utilisation est relativement similaire à l’ancien, il faut faire un HTTP GET sur une URL en passant des arguments.
Le format de la requête est le suivant :

ACTION=(schedule-svc-downtime|remove-svc-downtime|schedule-servicegroup-downtime)&MANDATORY_ARGUMENTS

Les MANDATORY_ARGUMENTS varient en fonction de l’action à réaliser :

  • Si ACTION=schedule-svc-downtime : les arguments obligatoires sont HOSTNAME,SERVICEDESC,DURATION,AUTHOR,COMMENT
  • Si ACTION=remove-svc-downtime: les arguments obligatoires sont HOSTNAME,SERVICEDESC
  • Si ACTION=schedule-servicegroup-downtime : les arguments obligatoires SERVICEGROUP,DURATION,AUTHOR,COMMENT

Avec :

  • HOSTNAME le host_name défini dans nagios
  • SERVICEDESC le service_description défini dans nagios
  • DURATION la durée en seconde de downtime
  • SERVICEGROUP le servicegroups défini dans nagios
  • AUTHOR le nom du contact dans nagios

Les avantages de ce nouveaux scripts sont :

  • La possibilité de gérer de multiples serveurs nagios d’un seul endroit
  • De ne pas avoir à tourner forcément sur le serveur de supervision
  • D’être compatibles avec tous les systèmes de supervision ayant un broker livestatus (testé avec Nagios et Shinken)

Si vous avez des commentaires, n’hésitez pas !

Share

Contrôlez l’alimentation de vos serveurs avec Foreman

La gestion de l’alimentation de vos serveurs est une nouveauté apportée par la version 1.2. il vous faudra avoir installé au préalable (Foreman et smart-proxy) à la dernière version stable.
Vous pouvez grâce à celle-ci allumer, éteindre ou rebooter vos serveurs physique directement depuis l’interface web ou via l’API REST grâce à l’IPMI.
Ceci à été testé sur des serveurs DELL en configurant le DRAC.

Configuration du smart-proxy

Pour cela au niveau de votre smart-proxy,
il vous faut :
* La gem rubyipmi installée

# gem install rubyipmi

* ipmitool d’installé :

# apt-get install ipmitool

Configuration dans Foreman

Editez un hôte dont vous souhaitez manager l’IPMI :

  • Par exemple allez sur foreman/hosts/server.example.com/edit
  • Cliquez sur l’onglet network
  • Cliquez sur ‘Add Interface’ 
  • Type => ‘BMC’

Vous pouvez récupérer la MAC adresse de l’interface BMC en vous connectant en SSH sur server.example.com et utiliser la commande ipmitool suivante :

# ipmitool lan print
  • Au niveau du nom de l’interface et du domaine, Foreman va rajouter automatiquement un enregistrement DNS, cependant il existe un bug dans la version 1.2.0 car l’enregistrement se fait sans le domaine suffixé (voir bug ouvert). Je vous conseil donc pour le moment de mettre le le fqdn et non pas juste le nom (par exemple server-ipmi.example.com)
  • Choisissez un user / password puis sauvegardez.

Configuration de la carte IPMI

Sur le serveur en lui même, il vous faut encore configurer la carte BMC pour autoriser Foreman à l’utiliser.
Voici les commandes IPMI à utiliser :

# ipmitool lan set 1 ipsrc dhcp
# ipmitool lan set 1 access on
# ipmitool user set name 3 your_user
# ipmitool user set password 3 your_password
# ipmitool channel setaccess 1 3 callin=on ipmi=on link=on privilege=4
# ipmitool user enable 3

Utilisation de la fonctionnalité

Sur la page de votre hôte, si tout s’est bien passée, vous devriez pouvoir piloter depuis Foreman son alimentation :

bmc

Voila, encore une intégration de plus entre Foreman et l’ensemble de vos serveurs. Foreman s’améliore de release en release !

Share

Supervision distribuée avec Nagios et Puppet

Historiquement j’utilisais un seul server Nagios3 pour superviser ma production dont la configuration était
complètement générée par Puppet avec Naginator.
Cette solution bien que contraignante (difficulté à gérer les seuils spécifiques d’alerte par exemple,
appliances non puppetisée, etc ..) est vraiment puissante et me permets de ne jamais me soucier de la configuration du monitoring :
je suis sur à tout moment que tous les serveurs dans mon environnement de production sont monitorés
et que chaque service définis dans Puppet à les services Nagios associés.
Cependant mes besoins ont évolués et j’ai commencé à avoir des problématiques de monitoring distribué assez classique :
4 datacenters répartis entre l’Europe et les USA, des problèmes récurrents de réseau
qui provoquaient de nombreux faux-positifs et un ras le bol de mails trop intempestifs.
Je n’avais pas de soucis particuliers de performances : j’ai moins de 200 hosts et 2000 services.

J’ai essayé Shinken, vraiment. Y’a 2 ans une première fois puis ces derniers mois.
J’ai été obligé de le packager puisqu’aucun package Debian n’était proposé
et que tous nos serveurs sont déployés de manière unattended :
le script d’installation proposé n’était pas pour moi une solution envisageable.
Sur le papier Shinken était parfait :
* compatibilité de configuration avec Nagios
* support des directives spécifiques à Shinken dans Puppet avec Naginator
* support natif de distribution avec les realms ou poller_tag
* suport natif de la HA
* support natif de Livestatus
* une communauté sympas et des devs réactifs

Dans les faits et d’après mon expérience :
* la configuration n’est pas 100% interprétée de la même manière (mais les ajustements relativements triviaux)
* shinken prend énormément plus de RAM que nagios (même si Jean Gabès a pris le temps d’écrire un très long mail pour m’expliquer très clairement ce comportement)
* le plus important pour moi : l’ensemble n’est à mon humble avis pas assez stable / robuste dans mon cas d’usage : en cas de netsplit les démons n’arrivaient plus à se resynchroniser à la fin de l’outage, certains modules crashaient sans crier gare, des problèmes d’incompatibilité avec Pyro.

Je n’était pas assez confiant envers mon POC pour accepter de le mettre en production.

Pour être bien claire :
* Je continue de penser que Shinken sera à terme une des (sinon LA) solutions pour remplacer Nagios, mais il n’était pas encore prêt pour mes besoins.
* Certaines personnes font tourner Shinken en production, sur de grosses infras sans problèmes. Mon retour sur ce projet ne doit en aucun cas vous dissuader
de faire vos propres tests et de vous forger votre opinion.

J’ai du trouver une solution moins satisfaisante formellement mais qui repose sur des briques éprouvées.

Je suis donc partis sur l’ensemble des briques suivantes :
* Un server Nagios par datacenter pour le monitoring
* Puppet pour la gestion des configurations distribuée (il prend ici le rôle de l’arbiter de Shinken)
* Livestatus + Check_MK Multisite pour l’aggrégation des données

Nous utilisons énormément de Facts custom dans Puppet et nous avons donc
un Fact « $::hosting » qui nous indique dans quel datacenter se situe notre chaque host.
Afin de découper notre configuration entre chaque poller, j’utilise donc des targets dynamiques dans puppet pour les resources liées aux datacenter (hosts, services, hostescalation, serviceescalation):

Voici un exemple simplifié de ma définition d’host en Exported Resources :

        $puppet_conf_directory = '/etc/nagios3/conf.puppet.d'
        $host_directory = "$puppet_conf_directory/$::hosting"

        @@nagios_host { "$::fqdn" :
                tag           => 'nagios',
                address    => $::ipaddress_private,
                alias         => $::hostname,
                use           => "generic-host",
                notify        => Service[nagios3],
                target        => "$host_directory/$::fqdn-host.cfg",
        }

Toutes les resources communes à tous les pollers (contacts, contactgroups,
commands, timeperiods, etc…) sont générées dans un répertoire sourcé par tous les nagios
(ex: ‘/etc/nagios3/conf.puppet.d/common’).
Enfin dans le nagios.cfg je source pour chaque poller les dossiers des datacenters
que je souhaite monitorer depuis ce poller.

# Ex pour nagios1 : 
cfg_dir=/etc/nagios3/conf.puppet.d/common
cfg_dir=/etc/nagios3/conf.puppet.d/hosting1
# Pour nagios2 :
cfg_dir=/etc/nagios3/conf.puppet.d/common
cfg_dir=/etc/nagios3/conf.puppet.d/hosting2

J’ai pris le partis de ne pas utiliser les tags des exported resources :
ce la le permet d’avoir exactement les mêmes fichiers de configuration sur tous mes pollers dans /etc/nagios3/conf.puppet.d : seul nagios.cfg change entre les pollers.
En cas de soucis avec l’un de mes pollers, je peux très simplement ajouter le monitoring d’un autre datacenter en ajoutant l’inclusion d’un dossier en plus !
Cette configuration me permet donc d’avoir une supervision distribuée dont la configuration est homogène.

J’expliquerais dans un prochain article mon utilisation de Livestatus pour agréger l’ensemble des résultats de monitoring.

Share

Accélérez Foreman avec memcached

J’ai beau avoir Foreman qui tourne avec des versions récentes d’apache et passenger,
la vitesse n’est pas la principale qualité de cette application.
J’ai testé récemment un plugin écrit par Ohad Levy qui rajoute le support de Memcache à Foreman.
Le repo sur github est à cette adresse.
Je l’ai installé sans soucis en production sur mes Foreman 1.2, voici la marche à suivre :

J’utilise personnellement une installation de Foreman à partir de git, vous devrez peut être l’adapter
à votre installation.
Cette méthode est relativement similaire à l’installation de tout plugin dans Foreman :
le plugin s’installe comme une nouvelle gem.

Installation de memcached sur la machine Foreman:

# apt-get install memcached
# service memcached start

Par défaut Foreman utilise un memcached local.

# cd ~foreman
# echo "gem 'foreman_memcache', :git => \"http://github.com/ohadlevy/foreman_memcache.git\"" > bundler.d/memcache.rb
# bundle install --without postgresql sqlite test development --path vendor # que vous devez adapter au gem que vous installez d'habitude

On redémarre passenger pour relancer l’application :

# service apache2 restart

Voila Foreman devrait déjà être plus réactif !

Share

Intégration Puppet, Foreman et Mcollective

Depuis que nous avons déployé Foreman en production, nous n’avions jamais pu
utiliser le bouton ‘Run Puppet’ dans l’interface de Foreman car nous n’avons
pas de daemon puppet : il tourne en crontab.

Cependant la sortie de la version 1.2 de Foreman change la donne :
le support de mcollective est maintenant intégré dans les smart-proxies.

Voici la procédure pour le faire fonctionner. Je pars du principe que vous avez déjà
un mcollective et un Foreman fonctionnel.

Vous devez configurer tous les proxy qui déclarent la fonctionnalité ‘puppet’:
Sur les proxy:
On commence par installer le client mcollective et le plugin puppet :

# apt-get install mcollective-client mcollective-puppet-client

Pensez à configurer votre client mcollective (/etc/mcollective/client.cfg), cette configuration devrait être la même que votre desktop.
Vous devez ensuite autoriser l’utilisateur foreman-proxy à utiliser le client mcollective:

# visudo 
Defaults:foreman-proxy !requiretty
foreman-proxy ALL = NOPASSWD: /usr/bin/mco puppet runonce *

Dans la configuration du proxy :

:puppet: true
:puppet_provider: mcollective

Redémarrez votre proxy (pour ma part j’utilise apache et passenger) :

# service apache2 restart

Vous devriez pouvoir tester votre installation avec un simple appel curl :

$  curl   -d "nodes=myserver.example.com" https://myproxy:8443/puppet/run

Afin de pouvoir l’utiliser j’ai du ajouter dans ma configuration de mes daemon mcollective
la directive identity :

Dans /etc/mcollective/server.cfg

identity = myserver.example.com

Dans les paramètres de Foreman, il faut
passer la directive ‘puppetrun’ à ‘true’.

Cela devrait être bon, il vous suffit d’aller sur la page de votre host et cliquer sur le bouton ‘Run puppet’

Share

Faites tourner vos foreman-proxy avec passenger

J’ai récemment décidé de remplacer le démon Webrick utilisé habituellement par Foreman-Proxy
par Apache 2.4 et Passenger pour des question principalement d’industrialisation.
Comme nous allons le voir le setup est assez simple.
Je pars du principe que vous avez déjà installé apache et passenger (pour Foreman, Puppetmasterd, etc ..).

Mon installation de smart-proxy étant par Git, celui-ci est localisé dans /opt, je vous laisse adapter vos chemins !
La configuration d’apache est la suivante :

Listen 8444
<VirtualHost *:8444>
  ServerName foreman-proxy.example.com
  ServerAlias proxy1.example.com

  DocumentRoot /opt/smart-proxy/public

  RailsAutoDetect On
  PassengerTempDir /opt/smart-proxy/tmp
  AddDefaultCharset UTF-8
  HostnameLookups On

  SSLEngine on
  SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/proxy1.example.com.pem
  SSLCertificateFile /var/lib/puppet/ssl/certs/proxy1.example.com.pem
  SSLCACertificateFile /var/lib/puppet/ssl/certs/ca.pem

  <Directory /opt/smart-proxy/public>
     Require local
     Require ip 192.168.0.0/16 10.0.0.0/8
  </Directory>

  CustomLog ${APACHE_LOG_DIR}/foreman-proxy.example.com/access.log combined
  ErrorLog ${APACHE_LOG_DIR}/foreman-proxy.example.com/error.log
</VirtualHost>

J’ai choisi de ne pas faire écouter passenger sur le même port que le démon webrick, mais vous pouvez très bien utiliser le 8443.
On remarque que la configuration SSL ne se fait plus au niveau de la configuration du proxy mais directement dans apache.

Au niveau du proxy, il est important de savoir que pour le moment, la directive « :trusted_hosts » provoque une erreur 500.
Le bug à été remonté ici : http://projects.theforeman.org/issues/2259

Voila, il vous reste à arrêter votre daemon smart-proxy et relancer apache et c’est tout bon !
Attention, si vous avez changé de port d’écoute, penser à mettre à jour votre configuration au niveau de Foreman.

Share

Générer avec Puppet des certificat SSL avec des « Alternative Name »

J’avais besoins de cette fonctionnalité pour mettre en place la communication SSL entre mes deux serveurs Foreman et ses proxies.
Mon problème étant que mes serveurs Foreman sont utilisé en faillover (avec une VIP) avec un DNS généric et non pas en utilisant leur FQDN.
Ceci provoquait un problème avec le certificat puppet utilisé car l’adresse ne correspondait pas au CN exposé.
J’ai donc mis en place un certificat puppet dont le CN est le FQDN (ex:foreman1.example.com) de la machine et qui comprend en plus comme
‘Subject Alternative Name’ le nom du faillover utilisé (ex:foreman.example.com).

C’est très simple à réaliser mais l’info est pas très documentée sur le net.
Il faut commencer par révoquer et supprimer tous les certificats existants pour cette machine :
Sur le client (sur Debian) :

# rm -rf /var/lib/puppet/ssl

Sur le puppet master :

# puppet cert clean foreman1.example.com

Modifier le puppet.conf du client et lui ajouter la directive :

dns_alt_names = foreman.example.com

Puis lancer puppet sur le client pour forcer la création du nouveau certificat et envoyer la demande de signature au master :

# puppet agent -t --report --pluginsync

Sur le master vous pouvez voir une nouvelle demande de certificat et vous pouvez le signer :

# puppet cert list
  "foreman1.example.com" (SHA256) 2C:76:5B:85:67:28:1C:92:48:AA:10:22:44:C7:9B:A7:0D:9B:E2:A5:5F:10:71:87:B9:3F:46:E4:70:4B:43:6C (alt names: "DNS:foreman.example.com", "DNS:foreman1.example.com")
# puppet cert sign devshinken4.yzserv.com --allow-dns-alt-names

Vous avez donc maintenant un certificat signé par votre Puppet CA qui comprend un DNS Alt Name.

Share