Posts


As of June 2023 code signing requires that hardware tokens must be used. The following documentation is an opinionated way to to make this work using digicert. This document does not cover initial setup and purchase of ev code signing cert. This document will only cover using an ev hardware token with SafeNet.

DigiCert’s SafeNet instructions.

Sign a dotnet assembly

The hardware token must be attached to the computer. The SafeNet Authentication client tool must be running in the user session and logged in.

WILL NOT WORK IN RDP/SSH SESSION.

Example command syntax as of March 25, 2023.

.\signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /n "Certs Subject Name Goes Here" "C:\path\to\fileToSign.exe"

The above example will prompt you with for the hardwares signing token and it must be manually entered for each file signed.

Enable batch signing files

How to Enable Single Logon for a SafeNet Token

  1. Open SafeNet Authentication Client Tools.

Navigate to Start > Program Files > Safenet > Safenet Authentication Client Tools.

  1. Click the Advanced View icon (gold gear).
  2. In the menu tree in the left pane, select Client Settings.
  3. In the right pane, select the Advanced tab.
  4. On the Advanced tab, select the Enable single logon option.
  5. Click Save.
  6. To activate the single logon feature, log off from the computer and log on again.

With the above done SafeNet will only prompt once per session for the hardware signing token password.

Automated EV signing using signtool /kc

Export the certificate. See Automate Extended Validation (EV) code signing. The examples below is taken from that stackoverflow post. It has screenshots. Read it.

Ensure that the ** characters remain just replace the characters **THE_PASSWORD.


& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool.exe" sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /n "Certs Subject Name Goes Here" /f "C:\the\path\to\exported\cert.cer" /csp "eToken Base Cryptographic Provider" /kc "[THE_READER{{THE_TOKEN_PASSWORD}}]=THE_CONTAINER_NAME" "C:\path\to\fileToSign.exe"

For /kc the value should be in the format below:


[reader{{password}}]=name

Where:

  • reader (THE_READER) is the “Reader name” from the SafeNet Client UI
  • password (THE_TOKEN_PASSWORD) is your token password
  • name (THE_CONTAINER_NAME) is the “Container name” from the SafeNet Client UI

References


See the newer 2024-10-19 post dotnet crystal reports on linux via crystalcmd post.


old stuff

WARNING. Do not use. This is one big experiment.

crystalcmd is a:

Java and c# program to load json files into crystal reports and produce PDFs.

Server side hosting

IIS

Client side

Curl example

curl https://c.majorsilence.com/status

curl -F "reportdata=@test.json" -F "reporttemplate=@report.rpt" https:///export --output testout.pdf

# test localhost
curl -F "reportdata=@test.json" -F "reporttemplate=@report.rpt" https:///export --output testout.pdf

C# example

Add the package Majorsilence.CrystalCmd.Client to your project.

dotnet add package Majorsilence.CrystalCmd.Client 

cs code

DataTable dt = new DataTable();

// init reprt data
var reportData = new Majorsilence.CrystalCmd.Client.Data()
{
    DataTables = new Dictionary<string, string>(),
    MoveObjectPosition = new List<Majorsilence.CrystalCmd.Client.MoveObjects>(),
    Parameters = new Dictionary<string, object>(),
    SubReportDataTables = new List<Majorsilence.CrystalCmd.Client.SubReports>()
};

// add as many data tables as needed.  The client library will do the necessary conversions to json/csv.
reportData.AddData("report name goes here", "table name goes here", dt);

// export to pdf
var crystalReport = System.IO.File.ReadAllBytes("The rpt template file path goes here");
using (var instream = new MemoryStream(crystalReport))
using (var outstream = new MemoryStream())
{
    var rpt = new Majorsilence.CrystalCmd.Client.Report(serverUrl, username: "The server username goes here", password: "The server password goes here");
    using (var stream = await rpt.GenerateAsync(reportData, instream, _httpClient))
    {
        stream.CopyTo(outstream);
        return outstream.ToArray();
    }
}

By default, kubectl looks for a file named config in the $HOME/.kube directory. You can specify other kubeconfig files by setting the KUBECONFIG environment variable or by setting the –kubeconfig flag.

To set an alternative kubectl config path set the KUBECONFIG environment variable or set the –kubeconfig flag.

Example 1, KUBECONFIG

export KUBECONFIG=~/path/to/kubeconfig.yaml
kubectl get nodes

Example 2, –kubeconfig

kubectl get nodes --kubeconfig ~/path/to/kubeconfig.yaml

Reference


sudo apt install haproxy
sudo snap install certbot

Basic haproxy and letsencrypt installation and setup.

Generate a cert

certbot certonly --standalone -d [yoursubdomain.of.your.site.majorsilence.com] --non-interactive --agree-tos --email [your email address] --http-01-port=8899

Haproxy

/etc/haproxy/haproxy.cfg

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1>
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

frontend letsencrypt-frontend
    bind :80
    bind :::80
    mode http
    acl destination_letsencrypt-backend00 path_beg /.well-known/acme-challenge/
    use_backend letsencrypt-backend if destination_letsencrypt-backend00

frontend my-web-app-fe
    #bind *:80
    bind *:443 ssl crt /etc/lets-ecrypt/haproxy-gen/ alpn h2,http/1.1
    #http-request redirect scheme https unless { ssl_fc }

    # detect domains
    acl destination_somedomain100 hdr_beg(host) -i subdomain1.majorsilence.com
    acl destination_somedomain200 hdr_beg(host) -i subdomain2.majorsilence.com

    # specify backends
    use_backend somedomain1-backend if destination_somedomain100
    use_backend somedomain2-backend if destination_somedomain200

backend letsencrypt-backend
    mode http
    option forwardfor
    option httplog
    server certbot 127.0.0.1:8899

backend somdomain1-backend
    balance roundrobin
    option httpchk
    server server1 ip:port check
    server server2 ip:port check
    server server3 ip:port check

backend somedomain2-backend
    balance roundrobin
    option httpchk
    server server1 ip:port check
    server server2 ip:port check
    server server3 ip:port check

backend self signed certs

backend somedomain2-backend
    balance roundrobin
    option httpchk GET / HTTP/1.1
    server server1 ip:port ssl verify none
    server server2 ip:port ssl verify none
    server server3 ip:port ssl verify none

Test haproxy config

haproxy -c -V -f /etc/haproxy/haproxy.cfg

certbot updates

How can this be setup to run after the snap certbot systemd timer runs to renew?

cd /etc/systemd/system 
ls -l *certbot*

/etc/cron.daily/updatecertsforhaproxy

#!/usr/bin/env bash

# Renew the certificate
certbot renew

# Haproxy requires certs concatenated
mkdir -p /etc/lets-ecrypt/haproxy-gen
bash -c "cat /etc/letsencrypt/live/subdomain1.majorsilence.com/fullchain.pem /etc/letsencrypt/live/subdomain1.majorsilence.com/privkey.pem > /etc/lets-ecrypt/haproxy-gen/subdomain1.majorsilence.com.pem"

bash -c "cat /etc/letsencrypt/live/subdomain2.majorsilence.com/fullchain.pem /etc/letsencrypt/live/subdomain2.majorsilence.com/privkey.pem > /etc/lets-ecrypt/haproxy-gen/subdomain2.majorsilence.com.pem"

systemctl reload haproxy

References


Mac specific

If you do not have brew install it before proceeding. See https://brew.sh.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install node

Install visual studio for mac 2022

At the time of this writing it is in preview

https://visualstudio.microsoft.com/vs/mac/preview/

Install docker desktop for mac

See https://docs.docker.com/desktop/mac for more info.

Ubuntu linux specific

docker install

sudo apt install -y docker.io docker-compose

# docker permissions
#sudo groupadd docker
sudo usermod -aG docker $USER
sudo chown root:docker /var/run/docker.sock
sudo chown -R root:docker /var/run/docker
# this works but the group does not?  Why?
sudo chown $USER /var/run/docker.sock
newgrp docker

Nodejs install

See https://github.com/nodesource/distributions/blob/master/README.md#deb

curl -fsSL https://deb.nodesource.com/setup_17.x | sudo -E bash -
sudo apt-get install -y nodejs

Rider and dotnet

On linux use rider as the IDE.

# see https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu#2004-
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb

sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y dotnet-runtime-6.0 aspnetcore-runtime-6.0 dotnet-sdk-6.0

snap install rider --classic

Nuget

List nuget sources

dotnet nuget list source

Start fresh with just nuget.org

dotnet new nugetconfig

Add private nuget source

Add any private nuget sources that you need. This is optional.

dotnet nuget add source "https://[YourPrivateRegistry]/v3/index.json" -n [Feed Name] -u YourUserName -p YourPassword --store-password-in-clear-text

Restore

dotnet restore [Your Solution Name].sln