Quantcast
Channel: Windows – rakhesh.com
Viewing all 163 articles
Browse latest View live

Universal Groups are limited to other domains of the same forest

$
0
0

Lookie, an AD related post. Been ages since I did any AD work.

I always thought Universal groups could contain members from any domains in any forests. Coz back when I was learning about this stuff I guess there weren’t multiple forests – it was more about multiple domains. But turns out Universal  groups can only contain members from other domains of the same forest. If you want a group that can contain members from any domains (in any forests) then Domain Local is the one you want.

One lives and learns.


Maximized Citrix windows with FancyZones

$
0
0

Here’s a “first world” problem and my fancy solution for it. Don’t judge. 😀

We use Citrix at work. Not a big deal. But I like to hop between machines – like when I am on the couch I prefer using the laptop, in one of my rooms I have a Mac, and so on (not going into how what all devices I have, I love having multiple machines and I hate selling or throwing away older devices – am sentimental that way). ☺ Plus, with Citrix running I am wary of closing the laptop lid momentarily or staying away from it for a while lest Citrix disconnects. (*sighs* 😋)

It’s a bother opening Citrix on each of these so I hit upon this smart idea of launch Citrix from one of my Windows machines and basically RDPing into it. This way I can connect to work from any machine at home with a simple RDP. Smart, huh. Only catch was the resolutions – each screen has a different resolution – and I can’t do anything about it. I’d typically manually expand the window to suit each screen… if only I could do something about that extra step too.

It would be good if I could just maximize Citrix, but the stupid thing does a full screen whenever I maximize. I found some forum posts where people save the Registry keys of their resolutions and double click those to set the Citrix window size, but those didn’t work for me.

Enter FancyZones from PowerToys. I don’t use it much but I created one custom zone:

It’s basically a window that stretches the whole screen.

I also ticked these settings:

And left the default activation key setting:

Now if I drag the Citrix window anywhere and press Shift while doing so, it just maximizes it to fill the screen. (If I had more zones I might have to do something to select the right one, but I don’t have to worry about that). No more full screen, just maximize as I want.

Even better, once I do this on one machine when I RDP from anywhere else FancyZones ensures that the window is resized (thanks to those settings I ticked above). So no more resizing when I switch machines either. Awesome, huh! 😎

Update: Tick these two also in the layout so it is the default layout:

Playing with pass on macOS and Windows

$
0
0

A long time ago I had stumbled upon pass (website), thought it looked interesting, made a note to take a look at it later, and then forgot about it.

This week I was thinking I need some sort of a command line password manager to store my various secrets and stuff like that. Not passwords as such, but I have a lot of PowerShell code where I need to add API Keys or Entra ID App Registration client secrets etc., and I wanted some secure way of doing it. Until now I was storing these in separate files to the code, and referring to them in my code by sourcing the file with the secret.

To give an example, I would create a file like mysecret.ps1 with the following:

$apiKey = "xxxxx"

Then, in the actual code file I’d have a line like this:

. "/path/to/mysecret.ps1"

That sources the first file, and now I can use $apiKey in the code without actually putting it in the code. It’s not super secret coz anyone getting a hold of my machine can figure out the file with the secret from the code, and thus get the secret; but it’s way better than including the secret in my code itself, especially since the code is often pushed to GitHub or put in shared locations at work. I could pat myself on being half-secure, though not fully there. ☺

This week I decided to change that. I know password managers like BitWarden and 1Password have CLI options, but I didn’t want to use either of them (for one, the BitWarden CLI is quite a hassle to setup; and for another, most of these are work secrets and I didn’t want to mix them with my personal BitWarden). I came across pass again in some Reddit thread, and this time decided to explore it properly.

(BTW, fun fact that I didn’t know. pass is created by Jason A. Donenfeld, same person who created WireGuard. He’s got a very minimalistic approach to things, which I like).

The coolest thing about pass is how it’s very simple and follows the Unix Philosophy (write programs that do one thing and do it well). It stores the secrets by encrypting them with GPG (so it doesn’t reinvent the wheel there), and there’s no concepts of folders or metadata or whatever – things are pretty much free form.

I don’t want to go too much into the details of how to setup pass, as the official page has all the details (and it’s super simple) but here’s what I did. I started using it on macOS, so let’s start there.

macOS

I created a separate GPG key for use with pass. So let’s start with that.

First, install GPG if not already installed.

brew install gpg

Then generate a key.

gpg --full-generate-key

Follow the wizard. I went with the defaults: ECC (sign and encrypt), Curve 25519, does not expire, and filled in the rest of the details.

Next, I initialized pass using the GPG key I created above.

pass init "my pass key"

And that’s pretty much it! Then I can add/ remove/ view secrets…

# adding a secret
pass insert appId/0eb79d7c-4cb2-48eb-bf20-a9c91fad17f4

# adding another secret
pass insert webhook/automationaccount/runbook

# viewing a secret
pass appId/0eb79d7c-4cb2-48eb-bf20-a9c91fad17f4

# view all secrets
pass

# editing a secret
pass edit appId/0eb79d7c-4cb2-48eb-bf20-a9c91fad17f4

# removing a secret
pass rm appId/0eb79d7c-4cb2-48eb-bf20-a9c91fad17f4

# adding another secret
pass insert serviceAccounts/exchange/svc_newaccount01

As you can see it’s pretty free form. I stored an app Id called “appId/0eb79d7c-4cb2-48eb-bf20-a9c91fad17f4” under a “folder” called “appId”. But there’s nothing folderish about it… it’s just a free form place I chose to put it so things are a bit organized. I could have very well put the secret in the top level itself, or even move it after creating to a different folder.

Viewing a secret is super simple too – just pass followed by the path to the secret.

(See the official website for some tips on adding more metadata to the secret apart from just the password).

If the GPG passphrase is needed, pinentry usually pops up.

All these secrets are stored in a folder called .password-store in the home folder. Easy peasy. Each secret is a file of its own, and the “folders” you put them in when creating are also present in the file system.

Using any of these secrets from PowerShell is easy. Simply do:

$appId = "0eb79d7c-4cb2-48eb-bf20-a9c91fad17f4"
$clientSecret = Invoke-Command -ScriptBlock { pass appId/${appId} }

Windows

I wanted to have this setup on Windows too. There is no pass for Windows natively, so one must use WSL.

In WSL (Ubuntu) I installed pass.

sudo apt update && sudo apt install pass

I then exported the GPG key from macOS to here.

# macOS
# view all the private keys
gpg --list-secret-keys

# export the one I want, used by pass
gpg --export-secret-keys --armor PASS-KEY-ID

I was pretty basic and had the Windows machine opened via RDP, so I just copied the key that was output on macOS, and pasted it into a new file (called pass-private-key.asc in this case) in Windows. Then I did:

# windows
gpg --import pass-private-key.asc

# not needed I think, but trust it
gpg --edit-key PASS-KEY-ID

Type: trust
Select: 5 (ultimate trust)
Confirm: Type quit and press Enter.

Continuing to be pretty basic, I then zipped the .password-store folder on macOS and copied it over to Windows and extracted it in WSL. And that’s it, I now had the same password on Windows too.

Using pass in Windows is straight forward. Just add wsl before the command.

# Adding a secret
wsl pass insert appId/0eb79d7c-4cb2-48eb-bf20-a9c91fad17f4

# Viewing a secret
wsl pass appId/0eb79d7c-4cb2-48eb-bf20-a9c91fad17f4

# Via PowerShell
$appId = "0eb79d7c-4cb2-48eb-bf20-a9c91fad17f4" 
$clientSecret = Invoke-Command -ScriptBlock { wsl pass appId/${appId} }

I like to copy paste my code between macOS and Windows, and I didn’t want to keep adding wsl on the Windows side. So I made a batch file called pass.bat and put it in my PATH. (Thanks to ChatGPT for this idea actually! 🤖)

@echo off
wsl pass %*

Now I can use the same command between both OSes and code.

macOS again

OK, so how can I keep the passwords in sync between both? My initial idea was about write some code to zip it on the macOS side. I created the following function and added it to my .bash_profile.

function passCopy {
    local zipfile="$HOME/Downloads/pass.zip"

    # Remove existing ZIP file if it exists
    rm -f "$zipfile"
    
    cd $HOME/dotfiles && zip -r "$zipfile" .password-store/ && cd $HOME && osascript -e "set the clipboard to POSIX file \"$zipfile\""

    # I can't delete the file here coz macOS copies only a reference to the file, not the actual file contents. 
    # When you delete the file, the clipboard loses access to it.
}

This zips the folder and puts it in my Downloads folder and also copies it to the clipboard. ☺

Windows again

And on the Windows side I added this to .bash_profile in WSL.

function passExtract {
    local file_path="$HOME/pass.zip"
    local folder_path="$HOME/.password-store"
    if [ -f "$file_path" ]; then
        rm -rf "$folder_path"
        unzip "$file_path"
        rm -f "$file_path"
    else
        echo "File $file_path does not exist. No action taken."
    fi
}

So all I do now after making some changes in macOS (which is where I mostly work in), I type passCopy in the terminal (in Bash). Switch to Windows, go to the WSL folder in File Explorer, press Ctrl+V to paste the file, and in WSL terminal I type passExtract.

Not a 100% ideal but better than nothing!

macOS one more time!

Then I realized pass can integration with git. It was there in the man page but I missed that initially. Wow!

So all I do is:

# initialize git
# this will create a .git folder in .password-store and add all existing secrets as a commit
pass git init

# add remote
pass git remote add origin github:pass-store

# pushing, first time
pass git push -u --all

# pushing after any other changes
pass git push

With this in place, all I need to after any changes to pass is also do pass git push.

Windows one more time!

So now I can get rid of the copy pasting I was doing earlier. 😃

What I did is do one final copy and paste between the two OSes – this way the .password-store in Windows too is Git initialized. (I did this also coz I couldn’t find any instructions on how to initialize a new .password-store from Git in Windows. I think the steps would be to clone the git repo to .password-store and then use pass as usual, but I was too lazy to try).

Now I can add/ remove/ manage secrets in either Windows or macOS. Wherever I make changes I must do pass git push after making changes; and on the other side do pass git pull to get it. Sweet!

To make things simpler, I modified the pass.bat file I created above like this:

@echo off
wsl pass git pull
wsl pass %*

This pulls the secrets so I always have the latest version. Now I can make a change in macOS, and as long as I didn’t forget to do pass git push after making changes I should pick it up straight away in Windows/ WSL (update: see 1⃣ below).

One problem with this though, is that I use SSH to connect to GitHub and it kept prompting me for the passphrase of the SSH key. In WSL or Windows this was a one time affair as ssh-agent remembers it, but when running from Windows via wsl pass git pull it kept asking each time.

The fix for that was to add the following in .bash_profile or .bashrc in WSL:

# thanks to https://superuser.com/a/1828793
ssh_pid=$(pidof ssh-agent)

# If the agent is not running, start it, and save the environment to a file
if [ "$ssh_pid" = "" ]; then
        ssh_env="$(ssh-agent -s)"
        echo "$ssh_env" | head -n 2 | tee ~/.ssh_agent_env > /dev/null
fi

# Load the environment from the file
if [ -f ~/.ssh_agent_env ]; then
        eval "$(cat ~/.ssh_agent_env)"
fi

# add all the keys
ssh-add -l > /dev/null || ssh-add

This is needed so the ssh-agent session is shared across multiple WSL instances.

And I modifed pass.bat thus:

@echo off
wsl bash -c 'eval "$(cat ~/.ssh_agent_env)"; pass git pull'
wsl pass %*

This way before pass git pull runs it also pulls the ssh-agent info and both are run in the same bash session. No more passphrase prompts each time! Yay.

And that’s about it for now. Now I have a super simple CLI based password manager I can use on macOS and Windows for the various code I write, without saving secrets in plain text on either machine. 🤘

Updates:

1⃣ Created a function like this in .bash_profile or .bashrc in macOS. This will push after every operation. Might be an overkill.

function pass {
    $(brew --prefix)/bin/pass "$@"
    $(brew --prefix)/bin/pass git push
}

And this in PowerShell profile.

function pass {
    param(
        [Parameter(ValueFromRemainingArguments=$true)]
        [string[]]$args
    )

    & "${Global:BREW_PREFIX}/bin/pass" @args
    & "${Global:BREW_PREFIX}/bin/pass" git push
}

 

Viewing all 163 articles
Browse latest View live