The Conflagration Seen from the Hisamatsu District (1877-1882) - Kobayashi Kiyochika

A recap of 2024

2024 was a year full of ups and downs. But looking back, I can say that I achieved various goals and collected plenty of memories. In this post, I will recap 2024 and share my plans for 2025. Indie Hacking 2024: ✅ Launched 2 products 2025: 🏃‍♂️‍➡️ Launch 3 products 🏃‍♂️‍➡️ Reach 5K€ MRR 2024 was a successful year, in terms of projects. I have finally achieved my long-time goal of releasing projects on the side while working full-time. Of course, this required me to sacrifice some evenings and weekends, but gladly there isn’t much to do in Berlin during Winter other than drinking. ...

February 7, 2025 · 9 min · Serhat M. Dündar
Snow at Ochanomizu (1880) - Kobayashi Kiyochika

Disassociating corporate habits

Recently, I have been fascinated by the idea of building a digital micro-business and I started making efforts in this direction in my free time. In the beginning, I was thinking of doing what I’ve been always doing for the last 15 years, and writing code to develop solutions to the problems I observed and collected with minimal effort. How hard could it be? I have been coding for many years, and I already had solid proof of being able to develop complex software that can deal with millions of users simultaneously. The challenge of developing small tools that can ease the lives of some seemed the easiest considering what I’ve done and built so far. I was confident. ...

December 9, 2024 · 6 min · Serhat M. Dündar
Halage En Hollande (1867) - Johan Barthold Jongkind

A recap of 2023

Looking back, 2023 wasn’t a bad year at all. There are many events that I’m happy about and that I want to log and many moments I want to remember. Habits As a smoker for 17 years who tried all possible quitting methods, such as nicotine gums, e-cigarettes/vapors, and varenicline medicines (chantix®/champix®, etc.), I finally stopped smoking. It’s hard to explain where I got the motivation from, but one day I decided not to smoke and I’ve not smoked since then. While I quit smoking, I also quit synthetic sugar at the same time, and I believe this really helped with my quitting process. Combining to quit these two habits worked for me as my cravings were mainly about synthetic sugar, instead of nicotine. ...

January 8, 2023 · 4 min · Serhat M. Dündar
Landscape with Bridge (1652) - Pieter de Molijn

Go runtimes in AWS Lambda

Introduction AL2 runtimes and migrating from AL1 to AL2 for NodeJS, Python, Ruby, and .NET are pretty straightforward. The only exception is Go. Things are a bit cumbersome there as a custom runtime named provided.al2 comes into play. By the time of this writing, the following runtimes are provided by AWS: Name Identifier Operating system Architectures Node.js 18 nodejs18.x Amazon Linux 2 x86_64, arm64 Node.js 16 nodejs16.x Amazon Linux 2 x86_64, arm64 Node.js 14 nodejs14.x Amazon Linux 2 x86_64, arm64 Node.js 12 nodejs12.x Amazon Linux 2 x86_64, arm64 Python 3.9 python3.9 Amazon Linux 2 x86_64, arm64 Python 3.8 python3.8 Amazon Linux 2 x86_64, arm64 Python 3.7 python3.7 Amazon Linux x86_64 Java 11 java11 Amazon Linux 2 x86_64, arm64 Java 8 java8.al2 Amazon Linux 2 x86_64, arm64 Java 8 java8 Amazon Linux x86_64 .NET Core 3.1 dotnetcore3.1 Amazon Linux 2 x86_64, arm64 .NET 6 dotnet6 Amazon Linux 2 x86_64, arm64 .NET 5 dotnet5.0 Amazon Linux 2 x86_64 Go 1.x go1.x Amazon Linux x86_64 Ruby 2.7 ruby2.7 Amazon Linux 2 x86_64, arm64 Custom Runtime provided.al2 Amazon Linux 2 x86_64, arm64 Custom Runtime provided Amazon Linux x86_64 As can be seen above, the go1.x runtime is still on AL1 instead of AL2. One of the major differences between AL1 and AL2 is supported architectures. AL2 comes with arm64 support. To benefit from arm64 support, and to migrate to a more performance/cost-efficient AL2, provided.al2 is the only option for Go lambda functions. ...

November 19, 2022 · 4 min · Serhat M. Dündar
La Place de l'Eglise (1866) - Johan Barthold Jongkind

Securing webhooks

In this post, I will focus on the rationale behind some popular webhook security methods and will try to explain them in simple terms. 1. Basics Risks and Measures 1.1. Webhooks can be set to leak data silently Let’s assume you are a webhook provider and an attacker compromises the credentials of one of your clients. If your platform doesn’t notify users when a webhook is created or updated - the attacker can create a webhook silently and start leaking data without alerting anyone. This silent tunnel will let the attacker stay in the system longer undetected. Therefore: ...

September 18, 2022 · 7 min · Serhat M. Dündar
La Cote Saint Andre (1880) - Johan Barthold Jongkind

Deconstructing and understanding an SSL certificate

Checking SSL certificates on a browser is easy. Just click the green lock icon and you’re good to go. But what if doing the same in a more hacker way? This is where openssl comes into play. Let’s start by checking the SSL certificate of this website: openssl s_client -connect www.serhatdundar.com:443 depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA depth=0 C = US, ST = California, L = San Francisco, O = "GitHub, Inc.", CN = www.github.com --- Certificate chain 0 s:/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=www.github.com i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA --- Server certificate -----BEGIN CERTIFICATE----- MIIHMDCCBhigAwIBAgIQAkk+B/qeN1otu8YdlEMPzzANBgkqhkiG9w0BAQsFADBw MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz dXJhbmNlIFNlcnZlciBDQTAeFw0yMDA1MDYwMDAwMDBaFw0yMjA0MTQxMjAwMDBa MGoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T YW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxHaXRIdWIsIEluYy4xFzAVBgNVBAMTDnd3 dy5naXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsj49 ... -----END CERTIFICATE----- subject=/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=www.github.com issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA --- No client certificate CA names sent Server Temp Key: ECDH, X25519, 253 bits --- SSL handshake has read 3673 bytes and written 289 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES128-GCM-SHA256 Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Session-ID-ctx: Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TLS session ticket lifetime hint: 7200 (seconds) TLS session ticket: 0000 - xx xx 60 d0 86 88 c0 26-2e 67 c0 e0 01 84 09 ab .,`....&.x...... 0010 - xx xx 95 f2 fa fa 1f f6-01 06 e3 99 23 2d 69 9a i...........#-x. 0020 - xx xx d1 f6 98 35 b5 f4-8f 91 47 b1 8e a6 d4 d2 *....6....G..... 0030 - xx xx b2 f4 61 f1 b0 7d-43 cb 66 62 c6 15 52 ad \*..x..}C.fb..R. 0040 - xx xx c3 f9 a9 f3 f8 e7-f2 7f b8 d3 0e 02 d2 da /...x........... 0050 - xx xx 0f 8f c1 1c 6e b3-f0 ae 4c ac 4e f6 8d 7c g.....x...L.N..| 0060 - xx xx 3b 2a 77 b3 c2 f0-2b e3 9f 73 1e db 07 6c /.;*x...+..s...l 0070 - xx xx a3 b5 42 74 de 4b-55 73 15 cf b0 97 c7 84 <...Bx.KUs...... 0080 - xx xx 65 ee cc 68 35 68-76 ef 7b 4a 7b 41 b3 94 ..e..x5hv.{J{A.. 0090 - xx xx 57 3f 74 a8 e8 0a-ec de 8b 77 49 f9 33 b0 `0W?x......wI.3. Start Time: 1643082971 Timeout : 7200 (sec) Verify return code: 0 (ok) Let’s investigate this response piece by piece. ...

January 25, 2022 · 8 min · Serhat M. Dündar
Road near La Cote-Saint-Andre (1885) - Johan Barthold Jongkind

Storing passwords in a database: hashing, salts, and peppers

“How do you store passwords in a database”? A very common question for back-end-oriented interviews. After conducting hundreds of technical interviews on different levels, I can confidently say around 50% of the candidates can’t answer this question. The most common answer I often got is “there is a package/gem/library we use, and it manages the password part”. Well, yes, frameworks, libraries, and packages cover most of the complexity nowadays, but I don’t accept this as an excuse for not being curious about essentials. Frameworks, packages, libraries, tools, text editors - they come and go all the time, but essentials just don’t. The ways we use to store passwords haven’t been changed much since I started programming, which was 15 years ago. ...

January 24, 2022 · 5 min · Serhat M. Dündar
Bords de riviere (1868) - Johan Barthold Jongkind

A primitive hashing function in Go

Cryptographic hash functions are complex mathematical calculations. Therefore understanding them requires a considerable amount of time and patience. However, they all have things in common: an input, a cryptographic algorithm, and an output. Recently, I had a chance to study some popular cryptographic hash functions, such as MD5 and SHA-1, and tried to understand how they really work. Wikipedia pages I linked include a considerable amount of information already, and more can be found online, but what I want to do was understand similarities between them and write my own primitive hashing function in Go. ...

January 23, 2022 · 4 min · Serhat M. Dündar
Paysage a la Côte Saint-Andre (1886) - Johan Barthold Jongkind

SSL/TLS handshake, hybrid encryption and public key infrastructure (PKI)

Hybrid Encryption: Symmetric and Asymmetric Encryption Combined Both symmetric and asymmetric encryption has advantages and disadvantages. So, which one should we use? Well, nowadays we often use them together. Asymmetric encryption is often used to exchange private keys between parties securely. In other words, parties who would communicate establish an asymmetric encryption protocol in the beginning just to exchange private keys. When the private key exchange is completed, they keep communicating by using symmetric encryption - which is faster than asymmetric encryption. This is also how SSL/TLS works. ...

January 22, 2022 · 6 min · Serhat M. Dündar
Rue A Saint-Parize-Le-Chatel, Pres De Nevers (1862) - Johan Barthold Jongkind

Symmetric and asymmetric encryption

Symmetric Encryption (Private Key Cryptography) In symmetric encryption only a single key, in other words, a private key is used to encrypt and decrypt a message. Symmetric encryption is also known as “Private Key Cryptography” as the whole encryption is only based on a private key. Some popular symmetric encryption algorithms are: Algorithm Cipher Key Size Block/State Size Popularity Notes AES Block 128, 192, or 256 bits 128 bits 1 The best one. Still in use. Blowfish Block 32-448 bits 64 bits 2 Still quite safe, but slower than AES. Twofish Block 128, 192, or 256 bits 128 bits 3 Still quite safe, but slower than AES. DES Block 56 bits 64 bits 4 Not considered as safe anymore. 3DES Block 112, or 168 bits 64 bits 4 Not considered as safe anymore. RC4 Stream 40-2048 bits 2064 bits 4 Not considered as safe anymore. Pros of symmetric encryption: ...

January 21, 2022 · 13 min · Serhat M. Dündar
La Campagne Nivernaise (1873) - Johan Barthold Jongkind

Canary AWS Lambda deployments

Lambdas aren’t easy. This isn’t just a provocative start, but instead my overall experience planning, creating, and deploying them. Let’s be honest, making something up and running requires plenty of AWS knowledge. One might get lost easily even inside IAM alone. IAM groups, IAM users, IAM roles, IAM group policy attachments, IAM policy documents, IAM role policies - and how they connect is confusing enough considering what Lambda promises, simplicity. And this is just IAM. ...

June 14, 2021 · 10 min · Serhat M. Dündar
Cart on the Beach at Etretat (1862) - Johan Barthold Jongkind

Book review: The Design of Web APIs

Title: The Design of Web APIs ISBN13: 978-1617295102 Publisher: Manning WWW: https://www.manning.com/books/the-design-of-web-apis Pages: 389 I recently had a chance to read “The Design of Web APIs” from Manning Publishing. The book is inspired by “The Design of Everyday Things”, the legendary writing of Donald Norman, that I still own as an original hard-copy printed in 1990. I like this masterpiece not because I studied Donald Norman quite a lot during my PhD studies (especially during the Human-Computer Interaction course), but also it’s still very relevant writing. ...

May 2, 2021 · 3 min · Serhat M. Dündar
Le Spui A La Haye (1868) - Johan Barthold Jongkind

Packing JS projects for AWS Lambda with Grunt

Grunt is a Javascript task runner. It automates repetitive tasks like minification, compilation, unit testing, linting, etc. So it’s also quite useful for packing JS projects for AWS Lambda. Install the CLI globally: npm install -g grunt-cli Add it to the package.json: npm install grunt --save-dev The Gruntfile.js or Gruntfile.coffee file is a valid JavaScript or CoffeeScript file that belongs in the root directory of your project. A Gruntfile is comprised of the following parts: ...

May 2, 2020 · 1 min · Serhat M. Dündar
Notre Dame of Paris seen from the Quai de la Tournelle (1863) - Johan Barthold Jongkind

Rails and PostgreSQL: types

During nokul we’ve heavily implemented PostgreSQL features into our Rails application. Unfortunately, ActiveRecord doesn’t come with constraint support for PostgreSQL, but rein does a fantastic job covering what’s missing in ActiveRecord. We believe that, one shouldn’t rely on a web application, that is very prone for human-error, when it comes to data integrity. Therefore our PostgreSQL tables included various constraints and limits. Below you will find a set of rules that we’ve investigated, implemented and battle tested with various types. ...

November 9, 2018 · 5 min · Serhat M. Dündar
Le Treport, Le Matin, Normandie (1852) - Johan Barthold Jongkind

Rails and PostgreSQL: constraints

During nokul we’ve heavily implemented PostgreSQL features into our Rails application. Unfortunately, ActiveRecord doesn’t come with constraint support for PostgreSQL, but rein does a fantastic job covering what’s missing in ActiveRecord. We believe that, one shouldn’t rely on a web application, that is very prone for human-error, when it comes to data integrity. Therefore our PostgreSQL tables included various constraints and limits. Below you will find a set of rules that we’ve investigated, implemented and battle tested with various types. ...

November 3, 2018 · 3 min · Serhat M. Dündar
The Church of Overschie (1866) - Johan Barthold Jongkind

Tuning PostgreSQL configuration

Configuration File RAM amounts defined below doesn’t represent the total amount of memory available for your machine, instead, it represents what PostgreSQL can use maximum. Decribed configuration requires PostgreSQL >= 10. Remove max_parallel_workers for older versions. The configuration file is usually located at /etc/postgresql/$VERSION/main/postgresql.conf in Debian-derivatives. For locating the file in other operating systems, you can use psql as follows: psql -U postgres show config_file; Tracking Query Statistics Enable the pg_stat extension, if you are interested in tracking query statistics: ...

November 2, 2018 · 1 min · Serhat M. Dündar
Landscape with Man on a Donkey (1849) - Johan Barthold Jongkind

Encrypting sensitive data with Rails

The most recent versions (5.1 and 5.2) of Ruby on Rails has shipped with a new feature named as encrypted credentials which replaces the secrets.yml, and enables you to keep sensitive data in an encrypted file named as config/credentials.yml.enc. However, this feature only works with a single file that is config/credentials.yml.enc. Recently we needed to add some data in our repository, which we wanted to keep as encrypted, but that also didn’t really fit into the credentials.yml.enc conceptually. ...

October 1, 2018 · 2 min · Serhat M. Dündar
Notre-Dame vue du quai de la Tournelle (1852) - Johan Barthold Jongkind

Rails instantiated fixtures

Here is a sample Ruby on Rails fixture named as newsletter: newsletter: name: foo message: bar first_name: foo last_name: bar There are two popular ways to use this fixture in your Rails tests. The first one is directly calling the name of fixture file, followed by a symbol stating the name of any individual fixture: class NewsletterTest < ActiveSupport::TestCase test 'a sample test' do assert newsletters(:newsletter).valid? end end And the other one is assigning fixtures to an instance variable in the setup block: ...

May 3, 2017 · 2 min · Serhat M. Dündar
Le Chateau De Virieu-Sur-Bourbre, Isere (1877) - Johan Barthold Jongkind

Import big MySQL databases faster

I recently had to import some quite large SQL dumps to my local machine for data analysis purposes. There were 10 different .sql dumps in total, and each of them were sized more than 100GB. Naive Attempt First of all, I tried to import each by using the < operator: mysql some_database < some_dump.sql Unsurprisingly, each task took very long to finish, approximately 6-7 hours per dump file, in a brand new laptop with i7 CPU, 16GB RAM and 1TB SSD. Since I didn’t have 60 hours for importing all, I had to take a look for solutions that can potentially speed up the process. ...

April 5, 2017 · 2 min · Serhat M. Dündar
Ornacieux (1879) - Johan Barthold Jongkind

Running rake tasks in a loop

Rake tasks in a loop, will only executed once if they are not “re-enabled”. Take a look at this example: namespace :yoksis do desc 'fetches all references' task :references do mapping = { get_instruction_language: 'UnitInstructionLanguage', get_instruction_type: 'UnitInstructionType' } mapping.each do |action, klass| Rake::Task['yoksis:reference'].invoke(action, klass) end end desc 'fetch an individual reference' task :reference, %i[soap_method klass] => [:environment] do |_, args| puts args[:soap_method] puts args[:klass] end end When you run the yoksis:references task, it will only print out {get_instruction_language: 'UnitInstructionLanguage'} and will skip the second item of the mapping hash. ...

April 3, 2017 · 1 min · Serhat M. Dündar