Batch Zertifikate erstellen per Batch

Shiva1990

Newbie
Registriert
Aug. 2021
Beiträge
5
Hallöle zusammen :)

Seit circa einer Woche durchforste ich die Tiefen des Internets nach einer passenden Lösung für mein Problem und doch wurde ich bisher nicht fündig, bzw fand ich nichts, was mir mit meinem aktuellen Kenntnisstand in irgeneiner Weise weiter half.

Ich bin in der Ausbildung zum Systemintegrator & habe primär nichts mit Programmierung zu tun, da mich die Materie allerdings sehr interessiert, bringe ich mir diese gerne selber bei. Da ich noch Anfänger bin, fehlt mir allerdings einfach noch ne Menge Wissen.

Ich wurde damit beauftragt eine Batch zu erstellen, welche automatisiert Zertifikate für eine VPN-Verbindung erstellt.
Wie ich das in der Kommandozeile an sich mache weiß ich mittlerweile aus dem FF aber um das Ganze in eine Batch umzusetzen, fehlt mir dann doch das know-how.

Bisher habe ich mich so weit in die Materie gewuselt, dass bestimmte Dinge hin und wieder (oder auch mal gar nicht) funktionieren und bin mittlerweile leider ratlos.
Hier mal der Code:


Code:
@Echo off
set home=C:\Program Files\OpenVPN\easy-rsa
cd %home%
echo %cd%
:start
SETLOCAL enabledelayedexpansion
[USER=116181]@Echo[/USER] Geben Sie die Gueltigkeit des Zertifikats an:
[USER=116181]@Echo[/USER] [1] = 10 Jahre; [2] = 20 Jahre; [3] = 30 Jahre; [4] = 40 Jahre; [5] = 50 Jahre
SET /P Jahre=Eingabe:

IF %Jahre% == 1 (
    ECHO Gueltigkeit auf 10 Jahre festgelegt.
    SET "build-ca.bat=C:\Program Files\OpenVPN\easy-rsa\build-ca.bat" (Habe hier jz nur eine Datei angegeben, sind aber insgesamt 5 die geändert werden müssen).
    SET "suchen=3650"
    SET "ersetzen_durch=3650"
) ELSE (
IF %Jahre% == 2 (
    ECHO Gueltigkeit auf 20 Jahre festgelegt.
    SET "build-ca.bat=C:\Program Files\OpenVPN\easy-rsa\build-ca.bat"
    SET "suchen=3650"
    SET "ersetzen_durch=7300"
) ELSE (
IF %Jahre% == 3 (
    ECHO Gueltigkeit auf 30 Jahre festgelegt.
    SET "build-ca.bat=C:\Program Files\OpenVPN\easy-rsa\build-ca.bat"
    SET "suchen=3650"
    SET "ersetzen_durch=10950"
) ELSE (
IF %Jahre% == 4 (
    ECHO Gueltigkeit auf 40 Jahre festgelegt.
    SET "build-ca.bat=C:\Program Files\OpenVPN\easy-rsa\build-ca.bat"
    SET "suchen=3650"
    SET "ersetzen_durch=14600"
) ELSE (
IF %Jahre% == 5 (
    ECHO Gueltigkeit auf 50 Jahre festgelegt.
    SET "build-ca.bat=C:\Program Files\OpenVPN\easy-rsa\build-ca.bat"
    SET "suchen=3650"
    SET "ersetzen_durch=18250"
) ELSE (
IF %Jahre% GTR 5 (
    goto start
    ECHO Ungueltige Eingabe.
IF %Jahre% LSS 1 (
    goto start
    ECHO Ungueltige Eingabe.
)
)
)
)
)
)

Ich kann in der CMD zwar eine Auswahl treffen und ich bekomme das entsprechende ECHO dazu, an den Dateien ändert sich jedoch gar nichts.

Schritt 1: Hier, was sie (grob übersetzt) tun soll:

@@+++Gültigkeit festlegen:@@

bei Eingabe x (1/2/3/4/5), ersetze entsprechende Gültigkeit (Textzeile: (standardmäßig) -days 3650) auf anzahl Tage: xxxxx (3650/7300/10950/14600/18250) in folgenden Dateien:
build-ca.bat
build-key.bat
build-key-pass.bat
build-key-pkcs12.bat
build-key-server.bat.

Hier noch ein weiterer Versuch, etwas ausladender aber leider auch komplizierter für mich:
(CMD Ausgabe unten)

Code:
@Echo off
set home=C:\Program Files\OpenVPN\easy-rsa
cd %home%
echo %cd%
:start
SETLOCAL enabledelayedexpansion
[USER=116181]@Echo[/USER] Geben Sie die Gueltigkeit des Zertifikats an:
[USER=116181]@Echo[/USER] [1] = 10 Jahre; [2] = 20 Jahre; [3] = 30 Jahre; [4] = 40 Jahre; [5] = 50 Jahre
set /p validity=Eingabe:

if %validity%==1 (
   echo Gueltigkeit auf 10 Jahre festgelegt.
   set gueltigkeit=3650
)
if %validity%==2 (
    echo Gueltigkeit auf 20 Jahre festgelegt.
    set gueltigkeit=7300
)
if %validity%==3 (
    echo Gueltigkeit auf 30 Jahre festgelegt.
    set gueltigkeit=10950
)
if %validity%==4 (
    echo Gueltigkeit auf 40 Jahre festgelegt.
    set gueltigkeit=14600
)
if %validity%==5 (
   echo echo Gueltigkeit auf 50 Jahre festgelegt.
   set gueltigkeit=18250
)
if %validity% GTR 5 (
   echo Ungueltige Eingabe.
   goto start
)
if %validity% LSS 1 (
   echo Ungueltige Eingabe.
   goto start
)
PAUSE
[USER=116181]@Echo[/USER] off
goto :if

:if %gueltigkeit% (
  set files[0]=build-ca
  set files[1]=build-key
  set files[2]=build-key-pass
  set files[3]=build-key-pkcs12
  set files[4]=build-key-server
 
  set "x=0"

  :SymLoop
  if defined files[%x%] (
    [USER=116181]@Echo[/USER] off
    setlocal EnableExtensions EnableDelayedExpansion
    set "INTEXTFILE=%%files[%x%].bat"
    set "OUTTEXTFILE=%%files[%x%]_temp.bat"
    set "REPLACETEXT=3650"

    findstr /m "-days 3650" %INTEXTFILE%
    if %errorlevel%==0 (
      set bisherigeGueltigkeit=3650
    )
    findstr /m "-days 7300" %INTEXTFILE%
    if %errorlevel%==0 (
      set bisherigeGueltigkeit=7300
    )
    findstr /m "-days 10950" %INTEXTFILE%
    if %errorlevel%==0 (
      set bisherigeGueltigkeit=10950
    )
    findstr /m "-days 14600" %INTEXTFILE%
    if %errorlevel%==0 (
      set bisherigeGueltigkeit=14600
    )
    findstr /m "-days 18250" %INTEXTFILE%
    if %errorlevel%==0 (
      set bisherigeGueltigkeit=18250
    )

  set /a "x+=1"

    set "SEARCHTEXT=%bisherigeGueltigkeit%"
    set "REPLACETEXT=%gueltigkeit%"
    set "modified=!%SEARCHTEXT%=%REPLACETEXT%!"
      echo !modified!>>"%OUTTEXTFILE%"
    )

    del "%INTEXTFILE%"
    rename "%OUTTEXTFILE%" "%INTEXTFILE%"

    goto :SymLoop
  ) else (
    echo "Bitte treffen Sie eine gültige Auswahl!"
    PAUSE
    goto :Choose
  )
)


batch error (2).JPG


Das war zwar bloß der Anfang & ich werde eure Hilfe sicher nochmal benötigen aber alles Schritt für Schritt..

Danke im Voraus!
 
Zuletzt bearbeitet:
Kenne mich jetzt mit easy-rsa nicht aus und kann nicht sagen was in diesen Files drin steht und was da passiert.
Aber muss es zwingend Batch sein? Ich denke PowerShell ist hier einfacher.
Ergänzung ()

PowerShell:
function Set-BatchContent {
    [CmdLetBinding()]
    param (
        [String] $Dauer = 3650
    )

    # Regex ist immer nett ;) - wir suchen nach "-days" und ersetzen die Zahl danach
    foreach ($BatchFile in ("build-ca.bat", "build-key.bat", "build-key-pkcs12.bat", "build-key-server.bat", "build-key-pass.bat") ) {
        (Get-Content -Path $BatchFile) -replace "(?<=-days\s)(\d*)", $Dauer | Set-Content -Path $BatchFile -Force
        Write-Verbose -Message "Datei: $BatchFile wurde geändert..."
    }
}

function Show-MainMenu {
    # Ein einfaches Menue
    Clear-Host
    Write-Host "1: 10 Jahre"
    Write-Host "2: 20 Jahre"
    Write-Host "3: 30 Jahre"
    Write-Host "4: 40 Jahre"
    Write-Host "5: 50 Jahre"
    Write-Host "`nQ: Beenden`n"
}

Set-Location -Path "C:\Program Files\OpenVPN\easy-rsa"

Clear-Host
do {
    Show-MainMenu
    $Auswahl = Read-Host "Waehlen Sie die gewünschte Gültigkeit des Zertifikates"
    switch ($Auswahl) {
        1 { Set-BatchContent -Dauer 3650 -Verbose }
        2 { Set-BatchContent -Dauer 7300 -Verbose }
        3 { Set-BatchContent -Dauer 10950 -Verbose }
        4 { Set-BatchContent -Dauer 14600 -Verbose }
        5 { Set-BatchContent -Dauer 18250 -Verbose }
        q { return }
        default { } # Bei Falscheinhaben kann hier noch eine Meldung rein
    }
    Start-Sleep -Seconds 2 # 2 Sekunden Pause, damit man die Ausgabe durch Write-Verbose sehen kann
}
until ($Auswahl -eq 'q')
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Shiva1990 und sikarr
Ich gucke ehrlich gesagt auch bei Batch wie die Maus ins Uhrwerk und würde Powershell bevorzugen. Aber ein paar Punkte hätte ich trotzdem.

1. Pack deinen Code doch bitte in die Codeansicht, da kannst du auch die Sprache auswählen und die andern können Code besser von Deinem Text trennen.
2. Habe ich sehr viel GOTO gelesen und weiß das dies sehr verpöhnt ist, mein Tipp würde ein SWITCH oder ELSEIF nicht mehr Sinn ergeben?

Gerade wenn du noch in der Ausbildung bist ist es von Vorteil wenn du dir das GOTO gar nicht erst angewöhnst, in vielen anderen Sprachen gibts das auch gar nicht.
 
Arvyr schrieb:
Kenne mich jetzt mit easy-rsa nicht aus und kann nicht sagen was in diesen Files drin steht und was da passiert.
Aber muss es zwingend Batch sein? Ich denke PowerShell ist hier einfacher.
Ergänzung ()

PowerShell:
function Set-BatchContent {
    [CmdLetBinding()]
    param (
        [String] $Dauer = 3650
    )

    # Regex ist immer nett ;) - wir suchen nach "-days" und ersetzen die Zahl danach
    foreach ($BatchFile in ("build-ca.bat", "build-key.bat", "build-key-pkcs12.bat", "build-key-server.bat", "build-key-pass.bat") ) {
        (Get-Content -Path $BatchFile) -replace "(?<=-days\s)(\d*)", $Dauer | Set-Content -Path $BatchFile -Force
        Write-Verbose -Message "Datei: $BatchFile wurde geändert..."
    }
}

function Show-MainMenu {
    # Ein einfaches Menue
    Clear-Host
    Write-Host "1: 10 Jahre"
    Write-Host "2: 20 Jahre"
    Write-Host "3: 30 Jahre"
    Write-Host "4: 40 Jahre"
    Write-Host "5: 50 Jahre"
    Write-Host "`nQ: Beenden`n"
}

Set-Location -Path "C:\Program Files\OpenVPN\easy-rsa"

Clear-Host
do {
Show-MainMenu
$Auswahl = Read-Host "Waehlen Sie die gewünschte Gültigkeit des Zertifikates"
    switch ($Auswahl) {
        1 { Set-BatchContent -Dauer 3650 -Verbose }
        2 { Set-BatchContent -Dauer 7300 -Verbose }
        3 { Set-BatchContent -Dauer 10950 -Verbose }
        4 { Set-BatchContent -Dauer 14600 -Verbose }
        5 { Set-BatchContent -Dauer 18250 -Verbose }
        q { return }
        default { } # Bei Falscheinhaben kann hier noch eine Meldung rein
    }
    Start-Sleep -Seconds 2 # 2 Sekunden Pause, damit man die Ausgabe durch Write-Verbose sehen kann
}
until ($Auswahl -eq 'q')

Meiner Meinung nach muss es nicht Batch sein, unser Geschäftsführer wollte es so, dieser kennt sich mit dem Thema allerdings gar nicht aus & im Endeffekt möchte er das ganze bloß automatisieren. Ich denke, im Prinzip ists dann egal, auf was für eine Datei er seinen Doppelklick ausführt, hauptsache es läuft ^^'

Werde es auf jeden Fall mal damit versuchen, hab Dank! :)
Ergänzung ()

sikarr schrieb:
Ich gucke ehrlich gesagt auch bei Batch wie die Maus ins Uhrwerk und würde Powershell bevorzugen. Aber ein paar Punkte hätte ich trotzdem.

1. Pack deinen Code doch bitte in die Codeansicht, da kannst du auch die Sprache auswählen und die andern können Code besser von Deinem Text trennen.
2. Habe ich sehr viel GOTO gelesen und weiß das dies sehr verpöhnt ist, mein Tipp würde ein SWITCH oder ELSEIF nicht mehr Sinn ergeben?

Gerade wenn du noch in der Ausbildung bist ist es von Vorteil wenn du dir das GOTO gar nicht erst angewöhnst, in vielen anderen Sprachen gibts das auch gar nicht.
1. Sorry, hab ich nachgeholt. Wollte ich ursprünglich so machen, hatte aber nichts dazu gefunden ^^'

2. Dann habe ich nun wieder was gelernt, danke :D
Das ist ja mein Problem, mir fehlt dann doch noch das Verständnis um zu wissen, was von all dem am meisten Sinn ergeben würde.
 
Zuletzt bearbeitet:
Hallo & danke an allen für die hilfreichen Denkanstösse!

Die Gültigkeit greife ich nun über die openssl config ab & somit brauch ich mich nicht um das Ändern der 5 anderen Dateien zu kümmern. Vielen Dank an dieser Stelle an Arvyr, denn du hast mir mit deinem Code gezeigt, dass es doch kein Hexenwerk ist & es doch tatsächlich zu bewerkstelligen ist! :D

ABER:
1. Ich bin ein bisschen zwischen Batch & Powershell hin und her gerissen (vor allem jz, wo ich sehen konnte, wie einfach es doch scheinbar sein kann).
2. Scheinbar gib es einfache Lösungen um Zertifikate per Powershell zu erstellen, da bleibt mir nur die Frage, wie ich das in diesem Fall mit der Gültigkeit der Zertifikate anstelle.
3. bzw. nutze ich ja die easy-rsa "Methode", nur hab ich keine Ahnung, ob ich stattdessen vielleicht ein Powershell Script nutzen (erstellen) kann, was mit der openssl config (bzw den 5 Dateien danach) arbeitet. Im Netz hab ich nichts im Zusammenhang bezüglich Powershell und easy-rsa gefunden, was mir geholfen hätte.

1: Was würdet ihr mir mehr raten?
2: Jemand eine Idee?
3: Ich hoffe ich habe mich halbwegs verständlich ausgedrückt, bin ja relativ neu im Game & bin mir manchmal auch noch nicht sicher, wie ich die Fragen richtig formuliere.

Mein Entweder/oder:

Entweder ich versuche alles weiter per Batch mit meinem easy-rsa-Kram, den ich mittlerweile gewohnt bin...
oder ich setze komplett auf die Powershell, weiß aber nicht, wie sich das mit easy-rsa verhält bzw muss ich herausfinden, wie ich Zertifikate per Powershell so erstelle, dass ich da ebenfalls an der Gültigkeit schrauben kann, das stellt mich nämlich vor der nächsten Herausforderung, da mir diese Abfolge völlig unbekannt ist.

Für easy-rsa hab ich mir überlegt, die Befehle, die normalerweise in die CMD eingetippt werden, als eben solche über die Powershell/CMD ausgeben und somit starten zu lassen. Das klappt zwar bei der init.config.bat, vars.bat & der clean-all.bat, nicht aber bei build-ca.bat & gerade diese ist ja für das Erstellen der Keys verantwortlich.

Ich hoffe, ihr versteht mein Dilemma & könnt mich erneut in die richtige Richtung weisen :D
 
Powershell ermöglicht dir, SelfSigned-Zertifikate zu erstellen, deine benötigten Parameter kannst du im CmdLet übergeben.

Das sind dann aber alles eigenständige Zertifikate.
Da ich, wie gesagt, von easy-rsa keine Ahnung habe und nicht weiß, ob eine PKI simuliert wird, musst du nur checken, wie und wo diese Zertifikate eingesetzt werden (sollen)

Einfach mal in die PowerShell Konsole oder ISE wechseln und eingeben
"Get-Command New-SelfSignedCertificate" bzw. "Get-Help New-SelfSignedCertificate"

Hier man ein Beispiel wie man ein solches Zertifikat mit PowerShell erstellen kann.

PowerShell:
 function New-VpnCertificate {
    param (
        [Switch]$EllipticCurve
    )
  
    # Hashtable für die einzelnen Parameter, macht das Lesen des Codes einfacher
    $SSCertHT = @{
        DnsName           = "fqdn"
        Subject           = "C=DE, ST=Bundesland, L=Stadt, O=Unternehmen, CN=fqdn"
        FriendlyName      = "VPN-Zertifikat"
        CertStoreLocation = "Cert:\LocalMachine\My"
        KeyExportPolicy   = "NonExportable" # Oder Exportable, je nach Bedarf
        NotAfter          = (Get-Date).AddYears(5) # Hier kommt die Dauer hin
        TextExtension     = "2.5.29.37={text}1.3.6.1.5.5.7.3.1" # Serverauthentifizierung
    }

    # Abhaengig vom Switchparameter den Keyalgorithmus auf EllipticCurve oder RSA setzen
    if ($EllipticCurve) {
        $SSCertHT.Add("KeyAlgorithm", "ECDSA_nistp256")   
    }
    else {
        $SSCertHT.Add("KeyAlgorithm", "RSA")
        $SSCertHT.Add("KeyLength", "2048")
    }

    try {
        # Neues selbstsigniertes Zertifikat erzeugen und den Thumbprint zurueckgeben
        $CertThumpPrint = New-SelfSignedCertificate @SSCertHT
    }
    catch {
        Write-Error -Message "ErrorType: $($Error[0].Exception.GetType().Fullname)"
        exit
    } 
}

Wichtig, das Zertifikat wird im Zertifikatsspeicher hinterlegt und nicht als Datei.
Es muss dann also erst ein mal exportiert werden.
Ergänzung ()

Ich empfehle, wenn es denn eine wirklich ordentliche Implementation von Zertifikaten sein soll, eine PKI aufzubauen.
Alles andere ist Bastelei (und Gültigkeitsdauer von solchen Endstellenzertifikaten von mehr als 10 Jahren ist gruselig.)
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Shiva1990
@Arvyr vielen lieben Dank, für deine Unterstützung. Hab mich mittlerweile auch ein bisschen mehr in die Materie rein gearbeitet, um zu verstehen was womit & aus welchem Grund wie funktioniert.
Mittlerweile habe ich mir folgenden Code zusammengefrickelt, welcher aber leider noch nicht einwandfrei funktioniert & hier erhoffe ich mir erneut Hilfe..

Vorab:
Step 1 & 2 funktionieren an sich (wobei ich bei Step 2 auch nicht sicher bin, da ich keine Veränderung wahrnehme), bei der Konvertierung hakts allerdings.
Fehlermeldungen schreibe ich unter den Code.
Weiter als bis zu Step 3 bin ich bisher nicht gekommen & ich stelle mir die Frage warum man bei Step 5 "cd /mnt/c/certs" braucht. Kenne diese Schreibweise nur von Linux und bin mir nicht sicher, ob das ganze Geschreibsel (bzw alles ab Step 3) nicht doch völlig unbrauchbar ist.

PowerShell:
# Step 1 - Create the root certificate

$params = @{
    DnsName           = "XXX-VPN-RootCA"
    KeyLength         = 4096
    KeyAlgorithm      = 'RSA'
    HashAlgorithm     = 'SHA512'
    KeyExportPolicy   = 'Exportable'
    NotAfter          = (Get-Date).AddYears(5)
    CertStoreLocation = 'Cert:\LocalMachine\My'
    KeyUsage          = 'CertSign','CRLSign' #fixes invalid cert error
    Textextension     = '2.5.29.37={text}1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.4,1.3.6.1.5.5.7.3.3,1.3.6.1.5.5.7.3.8,1.3.6.1.5.5.7.3.1','2.5.29.19={critical}{text}ca=TRUE'}
$rootCA = New-SelfSignedCertificate @params

# Step 2 - Create the server cert signed by the new root
 
$params = @{
  DnsName = "XXX-VPN"
  Signer = $rootCA
  KeyLength = 4096
  KeyAlgorithm = 'RSA'
  HashAlgorithm = 'SHA256'
  KeyExportPolicy = 'Exportable'
  NotAfter = (Get-date).AddYears(2)
  CertStoreLocation = 'Cert:\LocalMachine\My'
}
$vpnCert = New-SelfSignedCertificate @params

# Step 3 - Add Self-signed root to trusted root certificate store of current windows client

# Extra step needed since self-signed cannot be directly shipped to trusted root CA store
# if you want to silence the cert warnings on other systems you'll need to import the rootCA.crt on them too
Get-ChildItem -FilePath "Cert:\LocalMachine\My" | Export-Certificate -FilePath "C:\certs\rootCA.crt"
Import-Certificate -CertStoreLocation 'Cert:\LocalMachine\Root' -FilePath "C:\certs\rootCA.crt"

# Step 4 – Export server certificate as .pfx

Export-PfxCertificate -Cert $vpnCert -FilePath 'C:\certs\vpn.pfx' -Password (ConvertTo-SecureString -AsPlainText 'securepw' -Force)

# Step 5 – Extract server private key from .pfx to convert .crt to .pem

# enter bash session from cmd as admin and cd to directory containing vpn.pfx
cd /mnt/c/certs

# convert root ca certificate to pem format
openssl x509 -inform DER -in rootCA.crt -out rootCA.pem

# export server private key to pem format
openssl pkcs12 -in vpn.pfx -nocerts -nodes -out vpnkey.pem

# convert server certificate to pem format
openssl x509 -inform DER -in vpn.crt -out vpn.pem

PowerShell:
Get-ChildItem : Es wurde kein Parameter gefunden, der dem Parameternamen
"FilePath" entspricht.
In Zeile:34 Zeichen:15
+ Get-ChildItem -FilePath "Cert:\LocalMachine\My" | Export-Certificate  ...
+               ~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterBind
   ingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Command
   s.GetChildItemCommand
 
Import-Certificate : Die Zertifikatdatei wurde nicht gefunden.
In Zeile:35 Zeichen:1
+ Import-Certificate -CertStoreLocation 'Cert:\LocalMachine\Root' -File ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Import-Certificate], FileNotFoun
   dException
    + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.Certifica
   teServices.Commands.ImportCertificateCommand
 
Export-PfxCertificate : Das System kann den angegebenen Pfad nicht finden.
(Ausnahme von HRESULT: 0x80070003)
In Zeile:40 Zeichen:1
+ Export-PfxCertificate -Cert $vpnCert -FilePath 'C:\certs\vpn.pfx' -Pa ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Export-PfxCertificate], Director
   yNotFoundException
    + FullyQualifiedErrorId : System.IO.DirectoryNotFoundException,Microsoft.Cert
   ificateServices.Commands.ExportPfxCertificate
 
cd : Der Pfad "Cert:\mnt\c\certs" kann nicht gefunden werden, da er nicht
vorhanden ist.
In Zeile:46 Zeichen:1
+ cd /mnt/c/certs
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Cert:\mnt\c\certs:String) [Set-Loc
   ation], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocat
   ionCommand
 
openssl : Die Benennung "openssl" wurde nicht als Name eines Cmdlet, einer
Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt. Überprüfen
Sie die Schreibweise des Namens, oder ob der Pfad korrekt ist (sofern enthalten),
und wiederholen Sie den Vorgang.
In Zeile:49 Zeichen:1
+ openssl x509 -inform DER -in rootCA.crt -out rootCA.pem
+ ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (openssl:String) [], CommandNotFoun
   dException
    + FullyQualifiedErrorId : CommandNotFoundException
 
openssl : Die Benennung "openssl" wurde nicht als Name eines Cmdlet, einer
Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt. Überprüfen
Sie die Schreibweise des Namens, oder ob der Pfad korrekt ist (sofern enthalten),
und wiederholen Sie den Vorgang.
In Zeile:52 Zeichen:1
+ openssl pkcs12 -in vpn.pfx -nocerts -nodes -out vpnkey.pem
+ ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (openssl:String) [], CommandNotFoun
   dException
    + FullyQualifiedErrorId : CommandNotFoundException
 
openssl : Die Benennung "openssl" wurde nicht als Name eines Cmdlet, einer
Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt. Überprüfen
Sie die Schreibweise des Namens, oder ob der Pfad korrekt ist (sofern enthalten),
und wiederholen Sie den Vorgang.
In Zeile:55 Zeichen:1
+ openssl x509 -inform DER -in vpn.crt -out vpn.pem
+ ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (openssl:String) [], CommandNotFoun
   dException
    + FullyQualifiedErrorId : CommandNotFoundException
 
Zuletzt bearbeitet:
Hi

lösch doch bitte mal das "-FilePath" hinter dem "Get-Childitem", den kennt das cmd nämlich nicht, das ist schonmal der 1. Fehler.

mit "get-help" kannst du dir die Parameter der einzelnen cmdlets anzeigen lassen.

Und was tust du ab Step 5, das sieht mir nach bash aus?
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Shiva1990
sikarr schrieb:
Hi

lösch doch bitte mal das "-FilePath" hinter dem "Get-Childitem", den kennt das cmd nämlich nicht, das ist schonmal der 1. Fehler.

mit "get-help" kannst du dir die Parameter der einzelnen cmdlets anzeigen lassen.
Huhu Sikarr,

Danke, habe -FilePath zwar gelöscht, dann kommt aber folgendes:
Code:
Export-Certificate : Der Typ ist ungültig. Das Eingabeobjekt besitzt mehrere
Zertifikate.
In Zeile:1 Zeichen:41
+ ... LocalMachine\My" | Export-Certificate -FilePath "C:\certs\rootCA.crt"
+                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Export-Certificate], Win32Except
   ion
    + FullyQualifiedErrorId : System.ComponentModel.Win32Exception,Microsoft.Cert
   ificateServices.Commands.ExportCertificateCommand
 
Import-Certificate : Die Zertifikatdatei wurde nicht gefunden.
In Zeile:2 Zeichen:1
+ Import-Certificate -CertStoreLocation 'Cert:\LocalMachine\Root' -File ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Import-Certificate], FileNotFoun
   dException
    + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.Certifica
   teServices.Commands.ImportCertificateCommand

Habe meinen Zertifikatsspeicher ausgelesen, dieser ist allerdings leer. Verstehe die Fehlermeldung nicht 🤔

Tut mir leid, ich habe leider noch viel zu viele Fragezeichen über meinem Kopf & das Ganze übersteigt meine bisherigen Kompetenzen bei weitem, dennoch will ich nicht so einfach aufgeben.
 
Zuletzt bearbeitet:
Shiva1990 schrieb:
Danke, habe -FilePath zwar gelöscht, dann kommt aber folgendes:
Na du holst dir in Zeile 34 mit "Get-ChildItem -FilePath "Cert:\LocalMachine\My"" alle Zertifikate und dann Pipest du die zu Export-Certificate in eine Datei. Wenn du alle Zertifikate willst muss du das durch eine Schleife laufen lassen, wenn du nur ein bestimmtest suchst musst du noch angeben welches du eigentlich haben willst ;)
z.B.
PowerShell:
Get-childitem 'Cert:\LocalMachine\My' | where-object {$_.subject -eq "CN=XXX-VPN-RootCA"} | Export-Certificate -FilePath "C:\certs\rootCA.crt"
hier musst du aber beachten das der Name (subject) nicht eindeutig ist und du zur eindeutigen Identifikation über den "Thumbprint" gehen solltest wenn der Name nicht eindeutig ist.

Shiva1990 schrieb:
Tut mir leid, ich habe leider noch viel zu viele Fragezeichen über meinem Kopf & das Ganze übersteigt meine bisherigen Kompetenzen bei weitem, dennoch will ich nicht so einfach aufgeben.
Kein Problem.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Shiva1990
Ich schaue mal nach Zwecks des Trennens von Zertifikat und Schlüssel, denn das ist ja sicherlich, was du mit den Schritten am Ende bezwecken willst.
Das geht unter PowerShell natürlich nicht so mit bash.
Du kannst dir aber WinOpenSSL (https://slproweb.com/products/Win32OpenSSL.html) installieren. Dann kannst du zumindest die OpenSSL-Befehle ähnlich verwenden.

Ich schreib hier nachher mal Beispiele dazu.

Zu deinem Bisherigen Code (wusste gar nicht, dass man Self-Signed-Zertifikate als "Pseudo-CA" verwenden kann. Ergibt aber Sinn, da es in einer richtigen PKI nichts anderes ist ;) ) hier ein paar kleine Änderungen:

Ich verwende die Variablenzuweisung nicht umsonst
PowerShell:
$rootCA = New-SelfSignedCertificate @params
Anstatt mit Get-ChildItem zu suchen, kannst du hier nämlich diese Variable direkt verwenden.

Das sieht dann so aus:
PowerShell:
Export-Certificate -Cert $rootCA -FilePath "C:\certs\rootCA.crt"
Import-Certificate -CertStoreLocation 'Cert:\LocalMachine\Root' -FilePath "C:\certs\rootCA.crt"
Remove-Item -Path $rootCA.PSPath
Ich habe noch die Zeile zum Löschen des Zertifikates hinzugefügt.
Wenn du es als Rootzertifikat importierst, benötigen wir es nicht mehr unter den Eigenen.

oder gar noch einfacher:
PowerShell:
Move-Item -Path $rootCA.PSPath -Destination 'Cert:\LocalMachine\Root'

Bei den anderen Punkten schaue ich wie gesagt noch ein mal.
Ich meine da geht auch was mit .NET-Klassen.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Shiva1990 und sikarr
So, mit powershelleigenen Mitteln finde ich da keine schönere Lösung.
Also installier dir für dieses Dinge hier das oben angegebene WinOpenSSL.

Damit kannst du mit folgenden Zeilen dein Zertifikat je nach Bedarf "auspacken":

PowerShell:
# Pfad zur openssl.exe
$OpenSSLPath = 'C:\Program Files\OpenSSL-Win64\bin\openssl.exe'
# Ausgabeordner
$certspath = 'C:\certs'
# Passwort für das PFX-File
$pfxpasswd = 'securepw'

# Nur Private-Key
Start-Process -FilePath $OpenSSLPath -ArgumentList "pkcs12 -in $certspath\vpn.pfx -nocerts -out $certspath\private-key.pem -nodes -password pass:$pfxpasswd" -NoNewWindow -Wait
# Nur Zertifikate (alle)
Start-Process -FilePath $OpenSSLPath -ArgumentList "pkcs12 -in $certspath\vpn.pfx -nokeys -out $certspath\certs.pem -nodes -password pass:$pfxpasswd" -NoNewWindow -Wait
# Nur Clientzertifikat (ohne Key)
Start-Process -FilePath $OpenSSLPath -ArgumentList "pkcs12 -in $certspath\vpn.pfx -nokeys -clcerts -out $certspath\cl.pem -nodes -password pass:$pfxpasswd" -NoNewWindow -Wait
# Nur CA-Zertifikat ohne Key
Start-Process -FilePath $OpenSSLPath -ArgumentList "pkcs12 -in $certspath\vpn.pfx -nokeys -cacerts -out $certspath\ca.pem -nodes -password pass:$pfxpasswd" -NoNewWindow -Wait
Ergänzung ()

Bzw. wenn du dieses easy-rsa auf dem selben Rechner hast, dann sollte dort auch eine openssl.exe sein.
Dann kannst du auch diese verwenden. Sollte ja genauso funktionieren.
Du musst dann nur den Pfad zur .exe oben anpassen.
 
Zuletzt bearbeitet:
Ich schieb diesen etwas älteren Thread nochmal nach oben, weil es für mich auch interessant wäre, ob Du das mit dem Skript hinbekommen hast. Dabei wäre für mich vor allem interessant, ob Du die Client-Zertifikate via Skript erstellen konntest und falls ja, ob hierbei auch eine Möglichkeit zur Übergabe des Kennwortes besteht.

Hintergrund meiner Frage: für einen Jugendverband habe ich bei AWS ein VPN eingerichtet um einen gesicherten Datenbankzugriff zu ermöglichen. AWS bietet hierfür zwei verschiedene Möglichkeiten: entweder man nutzt Active Directory - oder Zertifikate, die via Easy-RSA erstellt werden. Ersteres erzeugt leider fortlaufend Kosten - daher haben wir uns vor Jahren schon für di Easy-RSA-Lösung entschieden.

Wie die Sache auf einer Virtuellen Linux-Instance eingerichtet wird, erklärt ein ausführlicher Beitrag von AWS:
https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/client-authentication.html#mutual

Da wir zu Beginn leider die Gültigkeitsdauer der Zertifikate nicht hochgestellt haben, laufen diese jetzt irgendwann aus. In Summe sind es aber doch eine ganze Reihe von Benutzern, für welche ich jetzt jeweils einzeln per Hand neue Zertifikate erstellen müsste. Das schreit förmlich nach einem Skript.

Zwar sieht die Dokumentation eine Variante ohne Kennworteingabe vor:

Code:
./easyrsa build-client-full client1.domain.tld nopass

Allerdings möchte ich aus Sicherheitsgründen auf jeden Fall ein Kennwort setzen. Nur wie bekomme ich das in einem Skript hin?

Ggf. bist Du damals ja schon weitergekommen.
 
Zurück
Oben